1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1998-2004, 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 16 public class ScriptList 17 { 18 static class LangSysRecord extends TaggedRecord 19 { 20 private Feature[] features; 21 private int featureCount; 22 LangSysRecord(String theLanguageTag)23 public LangSysRecord(String theLanguageTag) 24 { 25 super(theLanguageTag); 26 27 features = new Feature[10]; 28 featureCount = 0; 29 } 30 addFeature(Feature feature)31 public void addFeature(Feature feature) 32 { 33 if (featureCount > features.length) { 34 Feature[] newFeatures = new Feature[features.length + 5]; 35 36 System.arraycopy(features, 0, newFeatures, 0, features.length); 37 features = newFeatures; 38 } 39 40 features[featureCount++] = feature; 41 } 42 writeLangSysRecord(OpenTypeTableWriter writer)43 public void writeLangSysRecord(OpenTypeTableWriter writer) 44 { 45 writer.writeData(0); // lookupOrder (must be NULL) 46 writer.writeData(0xFFFF); // reqFeatureIndex (0xFFFF means none) 47 48 writer.writeData(featureCount); 49 50 for (int i = 0; i < featureCount; i += 1) { 51 writer.writeData(features[i].getFeatureIndex()); 52 } 53 } 54 } 55 56 static class ScriptRecord extends TaggedRecord 57 { 58 private LangSysRecord[] langSysRecords; 59 private int langSysCount; 60 ScriptRecord(String theScriptTag)61 public ScriptRecord(String theScriptTag) 62 { 63 super(theScriptTag); 64 langSysRecords = new LangSysRecord[10]; 65 langSysCount = 0; 66 } 67 findLangSysRecord(String languageTag)68 public LangSysRecord findLangSysRecord(String languageTag) 69 { 70 for (int i = 0; i < langSysCount; i += 1) { 71 LangSysRecord langSysRecord = langSysRecords[i]; 72 73 if (langSysRecord.getTag().equals(languageTag)) { 74 return langSysRecord; 75 } 76 } 77 78 if (langSysCount >= langSysRecords.length) { 79 LangSysRecord[] newLangSysRecords = new LangSysRecord[langSysCount + 5]; 80 81 System.arraycopy(langSysRecords, 0, newLangSysRecords, 0, langSysRecords.length); 82 langSysRecords = newLangSysRecords; 83 } 84 85 LangSysRecord newLangSysRecord = new LangSysRecord(languageTag); 86 langSysRecords[langSysCount] = newLangSysRecord; 87 88 langSysCount += 1; 89 return newLangSysRecord; 90 } 91 writeScriptRecord(OpenTypeTableWriter writer)92 public void writeScriptRecord(OpenTypeTableWriter writer) 93 { 94 TaggedRecord.sort(langSysRecords, langSysCount); 95 96 int scriptTableBase = writer.getOutputIndex(); 97 int firstLangSys = 0; 98 99 writer.writeData(0); // default langSys offset (fixed later) 100 101 if (langSysRecords[0].getTag().equals("(default)")) { 102 firstLangSys = 1; 103 } 104 105 writer.writeData(langSysCount - firstLangSys); 106 107 int langSysOffset = writer.getOutputIndex(); 108 109 for (int i = firstLangSys; i < langSysCount; i += 1) { 110 writer.writeTag(langSysRecords[i].getTag()); 111 writer.writeData(0); 112 } 113 114 if (firstLangSys > 0) { 115 System.out.print(" (default)"); 116 writer.fixOffset(scriptTableBase, scriptTableBase); 117 langSysRecords[0].writeLangSysRecord(writer); 118 } 119 120 for (int i = firstLangSys; i < langSysCount; i += 1) { 121 // fix the offset in the langSysRecordArray. 122 // The "+2" skips over the tag and the "+3" 123 // skips to the next langSysRecord entry 124 writer.fixOffset(langSysOffset + 2, scriptTableBase); 125 langSysOffset += 3; 126 127 System.out.print(" '" + langSysRecords[i].getTag() + "'"); 128 langSysRecords[i].writeLangSysRecord(writer); 129 } 130 } 131 } 132 133 private ScriptRecord[] scriptRecords; 134 private int scriptCount; 135 ScriptList()136 public ScriptList() 137 { 138 scriptRecords = new ScriptRecord[10]; 139 scriptCount = 0; 140 } 141 findLangSysRecord(String scriptTag, String languageTag)142 private LangSysRecord findLangSysRecord(String scriptTag, String languageTag) 143 { 144 for (int i = 0; i < scriptCount; i += 1) { 145 ScriptRecord scriptRecord = scriptRecords[i]; 146 147 if (scriptRecord.getTag().equals(scriptTag)) { 148 return scriptRecord.findLangSysRecord(languageTag); 149 } 150 } 151 152 if (scriptCount >= scriptRecords.length) { 153 ScriptRecord[] newScriptRecords = new ScriptRecord[scriptCount + 5]; 154 155 System.arraycopy(scriptRecords, 0, newScriptRecords, 0, scriptRecords.length); 156 scriptRecords = newScriptRecords; 157 } 158 159 ScriptRecord newScriptRecord = new ScriptRecord(scriptTag); 160 scriptRecords[scriptCount] = newScriptRecord; 161 162 scriptCount += 1; 163 return newScriptRecord.findLangSysRecord(languageTag); 164 } 165 addFeature(String scriptTag, String languageTag, Feature feature)166 public void addFeature(String scriptTag, String languageTag, Feature feature) 167 { 168 LangSysRecord langSysRecord = findLangSysRecord(scriptTag, languageTag); 169 170 langSysRecord.addFeature(feature); 171 } 172 writeScriptList(OpenTypeTableWriter writer)173 public void writeScriptList(OpenTypeTableWriter writer) 174 { 175 System.out.println("writing script list..."); 176 177 int scriptListBase = writer.getOutputIndex(); 178 179 TaggedRecord.sort(scriptRecords, scriptCount); 180 writer.writeData(scriptCount); 181 182 int scriptRecordOffset = writer.getOutputIndex(); 183 184 for (int i = 0; i < scriptCount; i += 1) { 185 writer.writeTag(scriptRecords[i].getTag()); 186 writer.writeData(0); 187 } 188 189 for (int i = 0; i < scriptCount; i += 1) { 190 // fix the offset in the scriptRecordArray. 191 // The "+2" skips over the tag and the "+3" 192 // skips to the next scriptRecord entry 193 writer.fixOffset(scriptRecordOffset + 2, scriptListBase); 194 scriptRecordOffset += 3; 195 196 System.out.print(" script '" + scriptRecords[i].getTag() + "':"); 197 scriptRecords[i].writeScriptRecord(writer); 198 System.out.println(); 199 } 200 } 201 } 202 203