@@ -196,16 +196,18 @@ open class TypesetString(
196196 val list = mutableListOf<GlyphRender >()
197197 var cursor = 0
198198 var combiningGap = 0
199+ var combiningWhitespace = false
199200 var combiningRectMin = Vec2i (0 , 0 )
200201 var combiningRectMax = Vec2i (0 , 0 )
201202 var combiningPosAfter = Vec2i (0 , 0 )
202- range.forEach {
203- val glyph = glyphFor(it )
204- val font = fontFor(it )
203+ range.forEach { index ->
204+ val glyph = glyphFor(index )
205+ val font = fontFor(index )
205206 val advance = glyph.calcAdvance(font.spacing)
206- val combiningClass = CombiningClass [UCharacter .getCombiningClass(codepoints[it ])]
207+ val combiningClass = CombiningClass [UCharacter .getCombiningClass(codepoints[index ])]
207208
208- if (combiningClass == CombiningClass .NOT_REORDERED ) {
209+ if (combiningClass == CombiningClass .NOT_REORDERED || combiningRectMin == combiningRectMax) {
210+ combiningWhitespace = UCharacter .isWhitespace(codepoints[index])
209211 combiningGap = max(1 , font.capHeight / 8 )
210212 combiningRectMin = Vec2i (
211213 cursor + glyph.bearingX, glyph.bearingY
@@ -215,14 +217,35 @@ open class TypesetString(
215217 )
216218 combiningPosAfter = Vec2i (cursor + advance, 0 )
217219 list.add(
218- GlyphRender (codepointIndices[it ], it , codepoints[it ], line,
220+ GlyphRender (codepointIndices[index ], index , codepoints[index ], line,
219221 font, glyph,
220222 Vec2i (cursor, 0 ), Vec2i (cursor + advance, 0 ),
221- attributedString.getAttributes(codepointIndices[it ]))
223+ attributedString.getAttributes(codepointIndices[index ]))
222224 )
223225 cursor + = advance
224226 } else {
225227 val cls = combiningClass
228+ if (cls == CombiningClass .DOUBLE_ABOVE || cls == CombiningClass .DOUBLE_BELOW &&
229+ index + 1 < codepoints.size && ! UCharacter .isWhitespace(codepoints[index+ 1 ])) {
230+ val nextGlyph = glyphFor(index + 1 )
231+ val nextFont = fontFor(index + 1 )
232+ combiningGap = max(combiningGap, nextFont.capHeight / 8 )
233+ if (combiningWhitespace) {
234+ combiningRectMin = Vec2i (
235+ combiningRectMin.x, nextGlyph.bearingY
236+ )
237+ combiningRectMax = Vec2i (
238+ combiningRectMax.x, nextGlyph.bearingY + nextGlyph.image.height
239+ )
240+ } else {
241+ combiningRectMin = Vec2i (
242+ combiningRectMin.x, min(combiningRectMin.y, nextGlyph.bearingY)
243+ )
244+ combiningRectMax = Vec2i (
245+ combiningRectMax.x, max(combiningRectMax.y, nextGlyph.bearingY + nextGlyph.image.height)
246+ )
247+ }
248+ }
226249 val rectMin = combiningRectMin
227250 val rectMax = combiningRectMax
228251 val gapX = if (cls.attached || cls.yAlign != 0 ) 0 else combiningGap
@@ -268,10 +291,10 @@ open class TypesetString(
268291 }
269292
270293 list.add(
271- GlyphRender (codepointIndices[it ], it , codepoints[it ], line,
294+ GlyphRender (codepointIndices[index ], index , codepoints[index ], line,
272295 font, glyph,
273296 Vec2i (newX, newY), combiningPosAfter,
274- attributedString.getAttributes(codepointIndices[it ]))
297+ attributedString.getAttributes(codepointIndices[index ]))
275298 )
276299 }
277300 }
0 commit comments