Skip to content

Commit 20a73e3

Browse files
yulian-gaponenkoiText-CI
authored andcommitted
Make glyphs independent in bidi-reordered line from pre-reordering
DEVSIX-5161
1 parent 110246b commit 20a73e3

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

layout/src/main/java/com/itextpdf/layout/renderer/TypographyUtils.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,7 @@ static int[] reorderLine(List<LineRenderer.RendererGlyph> line, byte[] lineLevel
222222
}
223223
}
224224

225-
// fix anchorDelta
226-
for (int i = 0; i < reorderedLine.size(); i++) {
227-
Glyph glyph = reorderedLine.get(i).glyph;
228-
if (glyph.hasPlacement()) {
229-
int oldAnchor = reorder[i] + glyph.getAnchorDelta();
230-
int newPos = inverseReorder[oldAnchor];
231-
int newAnchorDelta = newPos - i;
232-
glyph.setAnchorDelta((short) newAnchorDelta);
233-
}
234-
}
225+
updateAnchorDeltaForReorderedLineGlyphs(reorder, inverseReorder, reorderedLine);
235226

236227
line.clear();
237228
line.addAll(reorderedLine);
@@ -262,6 +253,24 @@ static List<Integer> getPossibleBreaks(String str) {
262253
return (List<Integer>) callMethod(TYPOGRAPHY_PACKAGE + WORD_WRAPPER, GET_POSSIBLE_BREAKS, new Class[] {String.class}, str);
263254
}
264255

256+
static void updateAnchorDeltaForReorderedLineGlyphs(int[] reorder, int[] inverseReorder,
257+
List<LineRenderer.RendererGlyph> reorderedLine) {
258+
for (int i = 0; i < reorderedLine.size(); i++) {
259+
Glyph glyph = reorderedLine.get(i).glyph;
260+
if (glyph.hasPlacement()) {
261+
int oldAnchor = reorder[i] + glyph.getAnchorDelta();
262+
int newPos = inverseReorder[oldAnchor];
263+
int newAnchorDelta = newPos - i;
264+
265+
if (glyph.getAnchorDelta() != newAnchorDelta) {
266+
glyph = new Glyph(glyph);
267+
reorderedLine.get(i).glyph = glyph;
268+
glyph.setAnchorDelta((short) newAnchorDelta);
269+
}
270+
}
271+
}
272+
}
273+
265274
private static Object callMethod(String className, String methodName, Class[] parameterTypes, Object... args) {
266275
return callMethod(className, methodName, (Object) null, parameterTypes, args);
267276
}

layout/src/test/java/com/itextpdf/layout/renderer/TypographyUtilsTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ This file is part of the iText (R) project.
4242
*/
4343
package com.itextpdf.layout.renderer;
4444

45+
import com.itextpdf.io.font.otf.Glyph;
46+
import com.itextpdf.layout.renderer.LineRenderer.RendererGlyph;
4547
import com.itextpdf.test.ExtendedITextTest;
4648
import com.itextpdf.test.annotations.type.UnitTest;
49+
50+
import java.util.Arrays;
51+
import java.util.List;
4752
import org.junit.Assert;
4853
import org.junit.Test;
4954
import org.junit.experimental.categories.Category;
@@ -56,4 +61,48 @@ public void verifyPdfCalligraphIsNotAvailable() {
5661
Assert.assertFalse(TypographyUtils.isPdfCalligraphAvailable());
5762
}
5863

64+
@Test
65+
public void updateAnchorDeltaMarkNotReorderedTest() {
66+
// original line 'abm', and 'm' is a mark based on 'b'
67+
Glyph mGlyph = new Glyph(100, 'm');
68+
mGlyph.setAnchorDelta((short) -1);
69+
mGlyph.setXAdvance((short) 15);
70+
mGlyph.setYAdvance((short) 25);
71+
72+
RendererGlyph b = new RendererGlyph(new Glyph(100, 'b'), null);
73+
RendererGlyph m = new RendererGlyph(mGlyph, null);
74+
RendererGlyph a = new RendererGlyph(new Glyph(100, 'a'), null);
75+
List<RendererGlyph> reorderedLine = Arrays.asList(b, m, a);
76+
77+
int[] reorder = new int[] {1, 2, 0};
78+
int[] inverseReorder = new int[] {2, 0, 1};
79+
80+
TypographyUtils.updateAnchorDeltaForReorderedLineGlyphs(reorder, inverseReorder, reorderedLine);
81+
82+
Assert.assertSame(mGlyph, m.glyph);
83+
Assert.assertEquals(-1, m.glyph.getAnchorDelta());
84+
}
85+
86+
@Test
87+
public void updateAnchorDeltaMarkReorderedTest() {
88+
// original line 'abm', and 'm' is a mark based on 'b'
89+
Glyph mGlyph = new Glyph(100, 'm');
90+
mGlyph.setAnchorDelta((short) -1);
91+
mGlyph.setXAdvance((short) 15);
92+
mGlyph.setYAdvance((short) 25);
93+
94+
RendererGlyph m = new RendererGlyph(mGlyph, null);
95+
RendererGlyph b = new RendererGlyph(new Glyph(100, 'b'), null);
96+
RendererGlyph a = new RendererGlyph(new Glyph(100, 'a'), null);
97+
List<RendererGlyph> reorderedLine = Arrays.asList(m, b, a);
98+
99+
int[] reorder = new int[] {2, 1, 0};
100+
int[] inverseReorder = new int[] {2, 1, 0};
101+
102+
TypographyUtils.updateAnchorDeltaForReorderedLineGlyphs(reorder, inverseReorder, reorderedLine);
103+
104+
Assert.assertNotSame(mGlyph, m.glyph);
105+
Assert.assertEquals(1, m.glyph.getAnchorDelta());
106+
}
107+
59108
}

0 commit comments

Comments
 (0)