1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1998-2007, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 * 9 * Created on Dec 3, 2003 10 * 11 ******************************************************************************* 12 */ 13 package com.ibm.icu.dev.tool.layout; 14 15 import java.util.Vector; 16 17 import com.ibm.icu.impl.Utility; 18 19 public class LigatureTreeWalker extends TreeWalker implements LookupSubtable 20 { 21 protected int[] componentChars; 22 protected int componentCount; 23 protected int lastFirstComponent; 24 25 protected Vector ligatureSets; 26 protected Vector ligatureSet; 27 28 public LigatureTreeWalker() 29 { 30 componentChars = new int[30]; 31 componentCount = 0; 32 lastFirstComponent = -1; 33 ligatureSet = null; 34 ligatureSets = new Vector(); 35 } 36 37 public void down(int ch) 38 { 39 componentChars[componentCount] = ch; 40 componentCount += 1; 41 } 42 43 public void up() 44 { 45 if (componentCount > 0) { 46 componentCount -= 1; 47 } 48 } 49 50 public void ligature(int lig) 51 { 52 int firstComponent = componentChars[0]; 53 54 if (lastFirstComponent != firstComponent) { 55 if (ligatureSet != null) { 56 ligatureSets.addElement(ligatureSet); 57 } 58 59 ligatureSet = new Vector(); 60 lastFirstComponent = firstComponent; 61 } 62 63 ligatureSet.addElement(new LigatureEntry(lig, componentChars, componentCount)); 64 } 65 66 public void done() 67 { 68 if (ligatureSet != null) { 69 ligatureSets.addElement(ligatureSet); 70 } 71 } 72 protected int firstComponentChar(int ligatureSetIndex) 73 { 74 Vector aLigatureSet = (Vector) ligatureSets.elementAt(ligatureSetIndex); 75 LigatureEntry firstEntry = (LigatureEntry) aLigatureSet.elementAt(0); 76 77 return firstEntry.getComponentChar(0); 78 } 79 80 protected void writeCoverageTable(OpenTypeTableWriter writer) 81 { 82 int ligatureSetCount = ligatureSets.size(); 83 84 writer.writeData(1); 85 writer.writeData(ligatureSetCount); 86 87 for (int set = 0; set < ligatureSetCount; set += 1) { 88 writer.writeData(firstComponentChar(set)); 89 } 90 } 91 92 public void writeLookupSubtable(OpenTypeTableWriter writer) 93 { 94 int coverageOffset, ligatureSetOffset, ligatureTableOffset; 95 int ligatureSubstitutionBase = writer.getOutputIndex(); 96 int ligatureSetCount = ligatureSets.size(); 97 98 //System.out.println("Writing " + tableName + "..."); 99 100 writer.writeData(1); // substFormat 101 102 coverageOffset = writer.getOutputIndex(); 103 writer.writeData(0); // coverageTableOffset (will fix later) 104 105 writer.writeData(ligatureSetCount); 106 107 ligatureSetOffset = writer.getOutputIndex(); 108 for (int set = 0; set < ligatureSetCount; set += 1) { 109 writer.writeData(0); // ligatureSet offset - will fix later 110 } 111 112 for (int set = 0; set < ligatureSetCount; set += 1) { 113 System.out.print(Utility.hex(firstComponentChar(set), 6) + ": "); 114 115 Vector aLigatureSet = (Vector) ligatureSets.elementAt(set); 116 int ligatureCount = aLigatureSet.size(); 117 int ligatureSetAddress = writer.getOutputIndex(); 118 119 System.out.println(ligatureCount + " ligatures."); 120 121 writer.fixOffset(ligatureSetOffset++, ligatureSubstitutionBase); 122 writer.writeData(ligatureCount); 123 124 ligatureTableOffset = writer.getOutputIndex(); 125 for (int lig = 0; lig < ligatureCount; lig += 1) { 126 writer.writeData(0); // ligatureTableOffset (will fix later) 127 } 128 129 for (int lig = 0; lig < ligatureCount; lig += 1) { 130 LigatureEntry entry = (LigatureEntry) aLigatureSet.elementAt(lig); 131 int compCount = entry.getComponentCount(); 132 133 writer.fixOffset(ligatureTableOffset++, ligatureSetAddress); 134 writer.writeData(entry.getLigature()); 135 writer.writeData(compCount); 136 137 for (int comp = 1; comp < compCount; comp += 1) { 138 writer.writeData(entry.getComponentChar(comp)); 139 } 140 } 141 } 142 143 writer.fixOffset(coverageOffset, ligatureSubstitutionBase); 144 writeCoverageTable(writer); 145 } 146 } 147