GposLookupType5 extends OpenTableLookup { @Override public boolean transformOne(GlyphLine line) { if (line.idx >= line.end) return false; if (openReader.isSkip(line.get(line.idx).getCode(), lookupFlag)) { line.idx++; return false; } boolean changed = false; GlyphIndexer ligatureGlyphIndexer = null; for (MarkToLigature mb : marksligatures) { OtfMarkRecord omr = mb.marks.get(line.get(line.idx).getCode()); if (omr == null) continue; if (ligatureGlyphIndexer == null) { ligatureGlyphIndexer = new GlyphIndexer(); ligatureGlyphIndexer.idx = line.idx; ligatureGlyphIndexer.line = line; while (true) { ligatureGlyphIndexer.previousGlyph(openReader, lookupFlag); if (ligatureGlyphIndexer.glyph == null) { break; } if (!mb.marks.containsKey(ligatureGlyphIndexer.glyph.getCode())) { break; } } if (ligatureGlyphIndexer.glyph == null) { break; } } List<GposAnchor[]> componentAnchors = mb.ligatures.get(ligatureGlyphIndexer.glyph.getCode()); if (componentAnchors == null) { continue; } int markClass = omr.markClass; for (int component = componentAnchors.size() - 1; component >= 0; component--) { if (componentAnchors.get(component)[markClass] != null) { GposAnchor baseAnchor = componentAnchors.get(component)[markClass]; GposAnchor markAnchor = omr.anchor; line.set(line.idx, new Glyph(line.get(line.idx), baseAnchor.XCoordinate - markAnchor.XCoordinate, baseAnchor.YCoordinate - markAnchor.YCoordinate, 0, 0, ligatureGlyphIndexer.idx - line.idx)); changed = true; break; } } break; } line.idx++; return changed; } GposLookupType5(OpenTypeFontTableReader openReader, int lookupFlag, int[] subTableLocations); @Override boolean transformOne(GlyphLine line);  }
@Test public void verifyMarkToBaseAttachment() throws IOException { TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.createFont(RESOURCE_FOLDER + "KhmerOS.ttf"); GlyphPositioningTableReader gposTableReader = fontProgram.getGposTable(); GposLookupType5 lookup = (GposLookupType5) gposTableReader.getLookupTable(0); List<Glyph> glyphs = Arrays.asList(new Glyph(fontProgram.getGlyphByCode(445)), new Glyph(fontProgram.getGlyphByCode(394))); GlyphLine gl = new GlyphLine(glyphs); gl.idx = 1; lookup.transformOne(gl); Assert.assertEquals(2, gl.size()); Assert.assertEquals(445, gl.get(0).getCode()); Assert.assertEquals(394, gl.get(1).getCode()); Assert.assertEquals(-1, gl.get(1).getAnchorDelta()); Assert.assertEquals(756, gl.get(1).getXPlacement()); }
@Test public void testSelectingCorrectAttachmentAlternative() throws IOException { TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.createFont(RESOURCE_FOLDER + "NotoNaskhArabic-Regular.ttf"); GlyphLine glyphLine = new GlyphLine(Arrays.asList(fontProgram.getGlyphByCode(513), fontProgram.getGlyphByCode(75))); GlyphPositioningTableReader gposTableReader = fontProgram.getGposTable(); GposLookupType5 lookup = (GposLookupType5) gposTableReader.getLookupTable(3); glyphLine.idx = 1; lookup.transformOne(glyphLine); Assert.assertEquals(2, glyphLine.size()); Assert.assertEquals(513, glyphLine.get(0).getCode()); Assert.assertEquals(75, glyphLine.get(1).getCode()); Assert.assertEquals(-1, glyphLine.get(1).getAnchorDelta()); Assert.assertEquals(-22, glyphLine.get(1).getXPlacement()); }
@Test public void testThatNoTransformationsAppliedForNonRelevantGlyphs() throws IOException { TrueTypeFont fontProgram = (TrueTypeFont)FontProgramFactory.createFont(RESOURCE_FOLDER + "NotoNaskhArabic-Regular.ttf"); GlyphLine glyphLine = new GlyphLine(Arrays.asList(fontProgram.getGlyph('1'), fontProgram.getGlyphByCode(75))); GlyphPositioningTableReader gposTableReader = fontProgram.getGposTable(); GposLookupType5 lookup = (GposLookupType5) gposTableReader.getLookupTable(3); glyphLine.idx = 1; lookup.transformOne(glyphLine); Assert.assertEquals(2, glyphLine.size()); Assert.assertEquals(1490, glyphLine.get(0).getCode()); Assert.assertEquals(75, glyphLine.get(1).getCode()); Assert.assertEquals(0, glyphLine.get(1).getAnchorDelta()); Assert.assertEquals(0, glyphLine.get(1).getXPlacement()); }