+ if(visualX < glyphPosition)
+ {
+ isBeforeFirstGlyph = true;
+ break;
+ }
+ }
+
+ // Whether the glyph can be split, like Latin ligatures fi, ff or Arabic (ل + ا).
+ Length numberOfCharacters = *(charactersPerGlyphBuffer + firstLogicalGlyphIndex);
+ if(direction != LTR)
+ {
+ // As characters are being traversed in visual order,
+ // for right to left ligatures, the character which contains the
+ // number of glyphs in the table is found first.
+ // Jump the number of characters to the next glyph is needed.
+
+ if(0 == numberOfCharacters)
+ {
+ // TODO: This is a workaround to fix an issue with complex characters in the arabic
+ // script like i.e. رّ or الأَبْجَدِيَّة العَرَبِيَّة
+ // There are characters that are not shaped in one glyph but in combination with
+ // the next one generates two of them.
+ // The visual to logical conversion table have characters in different order than
+ // expected even if all of them are arabic.
+
+ // The workaround doesn't fix the issue completely but it prevents the application
+ // to hang in an infinite loop.
+
+ // Find the number of characters.
+ for(GlyphIndex index = firstLogicalGlyphIndex + 1u;
+ (0 == numberOfCharacters) && (index < totalNumberOfGlyphs);
+ ++index)
+ {
+ numberOfCharacters = *(charactersPerGlyphBuffer + index);
+ }
+
+ if(2u > numberOfCharacters)
+ {
+ continue;
+ }
+
+ --numberOfCharacters;
+ }
+
+ visualIndex += numberOfCharacters - 1u;
+ }
+
+ // Get the script of the character.
+ const Script script = logicalModel->GetScript(characterLogicalOrderIndex);
+
+ const bool isInterglyphIndex = (numberOfCharacters > numberOfGlyphs) && HasLigatureMustBreak(script);
+ const Length numberOfBlocks = isInterglyphIndex ? numberOfCharacters : 1u;
+ const float glyphAdvance = glyphMetrics.advance / static_cast<float>(numberOfBlocks);
+
+ CharacterIndex index = 0;
+ for(; index < numberOfBlocks; ++index)