@@ -894,6 +894,8 @@ private static TextBox BreakLines(
894894 LayoutMode layoutMode )
895895 {
896896 bool shouldWrap = options . WrappingLength > 0 ;
897+
898+ // Wrapping length is always provided in pixels. Convert to inches for comparison.
897899 float wrappingLength = shouldWrap ? options . WrappingLength / options . Dpi : float . MaxValue ;
898900 bool breakAll = options . WordBreaking == WordBreaking . BreakAll ;
899901 bool keepAll = options . WordBreaking == WordBreaking . KeepAll ;
@@ -904,7 +906,6 @@ private static TextBox BreakLines(
904906
905907 int graphemeIndex ;
906908 int codePointIndex = 0 ;
907- float lineAdvance = 0 ;
908909 List < TextLine > textLines = new ( ) ;
909910 TextLine textLine = new ( ) ;
910911 int stringIndex = 0 ;
@@ -1073,7 +1074,7 @@ VerticalOrientationType.Rotate or
10731074 }
10741075 }
10751076
1076- // Now scale the advance.
1077+ // Now scale the advance. We use inches for comparison.
10771078 if ( isHorizontalLayout || shouldRotate )
10781079 {
10791080 float scaleAX = pointSize / glyph . ScaleFactor . X ;
@@ -1115,7 +1116,6 @@ VerticalOrientationType.Rotate or
11151116 descender -= delta ;
11161117
11171118 // Add our metrics to the line.
1118- lineAdvance += decomposedAdvance ;
11191119 textLine . Add (
11201120 isDecomposed ? new GlyphMetrics [ ] { metric } : metrics ,
11211121 pointSize ,
@@ -1153,58 +1153,60 @@ VerticalOrientationType.Rotate or
11531153 int maxLineBreakIndex = lineBreaks . Count - 1 ;
11541154 LineBreak lastLineBreak = lineBreaks [ lineBreakIndex ] ;
11551155 LineBreak currentLineBreak = lineBreaks [ lineBreakIndex ] ;
1156+ float lineAdvance = 0 ;
11561157
1157- lineAdvance = 0 ;
11581158 for ( int i = 0 ; i < textLine . Count ; i ++ )
11591159 {
11601160 int max = textLine . Count - 1 ;
11611161 TextLine . GlyphLayoutData glyph = textLine [ i ] ;
11621162 codePointIndex = glyph . CodePointIndex ;
11631163 int graphemeCodePointIndex = glyph . GraphemeCodePointIndex ;
1164- float glyphAdvance = glyph . ScaledAdvance ;
1165- lineAdvance += glyphAdvance ;
11661164
11671165 if ( graphemeCodePointIndex == 0 && textLine . Count > 0 )
11681166 {
1167+ lineAdvance += glyph . ScaledAdvance ;
1168+
11691169 if ( codePointIndex == currentLineBreak . PositionWrap && currentLineBreak . Required )
11701170 {
11711171 // Mandatory line break at index.
11721172 TextLine remaining = textLine . SplitAt ( i ) ;
11731173 textLines . Add ( textLine . Finalize ( options ) ) ;
11741174 textLine = remaining ;
1175- i = 0 ;
1175+ i = - 1 ;
11761176 lineAdvance = 0 ;
11771177 }
11781178 else if ( shouldWrap )
11791179 {
1180- float currentAdvance = lineAdvance + glyphAdvance ;
1181- if ( currentAdvance >= wrappingLength )
1180+ if ( lineAdvance >= wrappingLength )
11821181 {
11831182 if ( breakAll )
11841183 {
1185- // Insert a forced break at this index .
1184+ // Insert a forced break.
11861185 TextLine remaining = textLine . SplitAt ( i ) ;
1187- textLines . Add ( textLine . Finalize ( options ) ) ;
1188- textLine = remaining ;
1189- i = 0 ;
1190- lineAdvance = 0 ;
1186+ if ( remaining != textLine )
1187+ {
1188+ textLines . Add ( textLine . Finalize ( options ) ) ;
1189+ textLine = remaining ;
1190+ i = - 1 ;
1191+ lineAdvance = 0 ;
1192+ }
11911193 }
11921194 else if ( codePointIndex == currentLineBreak . PositionWrap || i == max )
11931195 {
1194- LineBreak lineBreak = currentAdvance == wrappingLength
1196+ LineBreak lineBreak = lineAdvance == wrappingLength
11951197 ? currentLineBreak
11961198 : lastLineBreak ;
11971199
11981200 if ( i > 0 )
11991201 {
12001202 // If the current break is a space, and the line minus the space
12011203 // is less than the wrapping length, we can break using the current break.
1202- float positionAdvance = lineAdvance ;
1204+ float previousAdvance = lineAdvance - ( float ) glyph . ScaledAdvance ;
12031205 TextLine . GlyphLayoutData lastGlyph = textLine [ i - 1 ] ;
12041206 if ( CodePoint . IsWhiteSpace ( lastGlyph . CodePoint ) )
12051207 {
1206- positionAdvance -= lastGlyph . ScaledAdvance ;
1207- if ( positionAdvance <= wrappingLength )
1208+ previousAdvance -= lastGlyph . ScaledAdvance ;
1209+ if ( previousAdvance <= wrappingLength )
12081210 {
12091211 lineBreak = currentLineBreak ;
12101212 }
@@ -1220,7 +1222,7 @@ VerticalOrientationType.Rotate or
12201222 {
12211223 if ( breakWord )
12221224 {
1223- // If the line is too long, insert a forced line break.
1225+ // If the line is too long, insert a forced break.
12241226 if ( textLine . ScaledLineAdvance > wrappingLength )
12251227 {
12261228 TextLine overflow = textLine . SplitAt ( wrappingLength ) ;
@@ -1233,7 +1235,7 @@ VerticalOrientationType.Rotate or
12331235
12341236 textLines . Add ( textLine . Finalize ( options ) ) ;
12351237 textLine = remaining ;
1236- i = 0 ;
1238+ i = - 1 ;
12371239 lineAdvance = 0 ;
12381240 }
12391241 }
@@ -1326,7 +1328,11 @@ public void Add(
13261328 {
13271329 // Reset metrics.
13281330 // We track the maximum metrics for each line to ensure glyphs can be aligned.
1329- this . ScaledLineAdvance += scaledAdvance ;
1331+ if ( graphemeIndex == 0 )
1332+ {
1333+ this . ScaledLineAdvance += scaledAdvance ;
1334+ }
1335+
13301336 this . ScaledMaxLineHeight = MathF . Max ( this . ScaledMaxLineHeight , scaledLineHeight ) ;
13311337 this . ScaledMaxAscender = MathF . Max ( this . ScaledMaxAscender , scaledAscender ) ;
13321338 this . ScaledMaxDescender = MathF . Max ( this . ScaledMaxDescender , scaledDescender ) ;
0 commit comments