1 /* 2 * Copyright 2010 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.typography.font.sfntly.table; 18 19 import com.google.typography.font.sfntly.Tag; 20 import com.google.typography.font.sfntly.data.ReadableFontData; 21 import com.google.typography.font.sfntly.data.WritableFontData; 22 import com.google.typography.font.sfntly.table.bitmap.EbdtTable; 23 import com.google.typography.font.sfntly.table.bitmap.EblcTable; 24 import com.google.typography.font.sfntly.table.bitmap.EbscTable; 25 import com.google.typography.font.sfntly.table.core.CMapTable; 26 import com.google.typography.font.sfntly.table.core.FontHeaderTable; 27 import com.google.typography.font.sfntly.table.core.HorizontalDeviceMetricsTable; 28 import com.google.typography.font.sfntly.table.core.HorizontalHeaderTable; 29 import com.google.typography.font.sfntly.table.core.HorizontalMetricsTable; 30 import com.google.typography.font.sfntly.table.core.MaximumProfileTable; 31 import com.google.typography.font.sfntly.table.core.NameTable; 32 import com.google.typography.font.sfntly.table.core.OS2Table; 33 import com.google.typography.font.sfntly.table.core.PostScriptTable; 34 import com.google.typography.font.sfntly.table.opentype.GSubTable; 35 import com.google.typography.font.sfntly.table.truetype.ControlProgramTable; 36 import com.google.typography.font.sfntly.table.truetype.ControlValueTable; 37 import com.google.typography.font.sfntly.table.truetype.GlyphTable; 38 import com.google.typography.font.sfntly.table.truetype.LocaTable; 39 40 41 /** 42 * A concrete implementation of a root level table in the font. This is the base 43 * class used for all specific table implementations and is used as the generic 44 * table for all tables which have no specific implementations. 45 * 46 * @author Stuart Gill 47 */ 48 public class Table extends FontDataTable { 49 50 private Header header; 51 Table(Header header, ReadableFontData data)52 protected Table(Header header, ReadableFontData data) { 53 super(data); 54 this.header = header; 55 } 56 57 /** 58 * Get the calculated checksum for the data in the table. 59 * 60 * @return the checksum 61 */ calculatedChecksum()62 public long calculatedChecksum() { 63 return this.data.checksum(); 64 } 65 66 /** 67 * Get the header for the table. 68 * 69 * @return the table header 70 */ header()71 public Header header() { 72 return this.header; 73 } 74 75 /** 76 * Get the tag for the table from the record header. 77 * 78 * @return the tag for the table 79 * @see #header 80 */ headerTag()81 public int headerTag() { 82 return this.header().tag(); 83 } 84 85 /** 86 * Get the offset for the table from the record header. 87 * 88 * @return the offset for the table 89 * @see #header 90 */ headerOffset()91 public int headerOffset() { 92 return this.header().offset(); 93 } 94 95 /** 96 * Get the length of the table from the record header. 97 * 98 * @return the length of the table 99 * @see #header 100 */ headerLength()101 public int headerLength() { 102 return this.header().length(); 103 } 104 105 /** 106 * Get the checksum for the table from the record header. 107 * 108 * @return the checksum for the table 109 * @see #header 110 */ headerChecksum()111 public long headerChecksum() { 112 return this.header().checksum(); 113 } 114 115 @Override toString()116 public String toString() { 117 StringBuilder sb = new StringBuilder(); 118 sb.append("["); 119 sb.append(Tag.stringValue(this.header.tag())); 120 sb.append(", cs=0x"); 121 sb.append(Long.toHexString(this.header.checksum())); 122 sb.append(", offset=0x"); 123 sb.append(Integer.toHexString(this.header.offset())); 124 sb.append(", size=0x"); 125 sb.append(Integer.toHexString(this.header.length())); 126 sb.append("]"); 127 return sb.toString(); 128 } 129 130 public abstract static class Builder<T extends Table> extends FontDataTable.Builder<T> { 131 private Header header; 132 Builder(Header header, WritableFontData data)133 protected Builder(Header header, WritableFontData data) { 134 super(data); 135 this.header = header; 136 } 137 Builder(Header header, ReadableFontData data)138 protected Builder(Header header, ReadableFontData data) { 139 super(data); 140 this.header = header; 141 } 142 Builder(Header header)143 protected Builder(Header header) { 144 this(header, null); 145 } 146 147 @Override toString()148 public String toString() { 149 return "Table Builder for - " + this.header.toString(); 150 } 151 152 /*********************************************************************************** 153 * 154 * Public Interface for Table Building 155 * 156 ***********************************************************************************/ 157 header()158 public final Header header() { 159 return this.header; 160 } 161 162 /*********************************************************************************** 163 * Internal Interface for Table Building 164 ***********************************************************************************/ 165 166 @Override notifyPostTableBuild(T table)167 protected void notifyPostTableBuild(T table) { 168 if (this.modelChanged() || this.dataChanged()) { 169 Header header = new Header(this.header().tag(), table.dataLength()); 170 ((Table) table).header = header; 171 } 172 } 173 174 // static interface for building 175 176 /** 177 * Get a builder for the table type specified by the data in the header. 178 * 179 * @param header the header for the table 180 * @param tableData the data to be used to build the table from 181 * @return builder for the table specified 182 */ getBuilder( Header header, WritableFontData tableData)183 public static Table.Builder<? extends Table> getBuilder( 184 Header header, WritableFontData tableData) { 185 186 int tag = header.tag(); 187 188 if (tag == Tag.cmap) { 189 return CMapTable.Builder.createBuilder(header, tableData); 190 } else if (tag == Tag.head) { 191 return FontHeaderTable.Builder.createBuilder(header, tableData); 192 } else if (tag == Tag.hhea) { 193 return HorizontalHeaderTable.Builder.createBuilder(header, tableData); 194 } else if (tag == Tag.hmtx) { 195 return HorizontalMetricsTable.Builder.createBuilder(header, tableData); 196 } else if (tag == Tag.maxp) { 197 return MaximumProfileTable.Builder.createBuilder(header, tableData); 198 } else if (tag == Tag.name) { 199 return NameTable.Builder.createBuilder(header, tableData); 200 } else if (tag == Tag.OS_2) { 201 return OS2Table.Builder.createBuilder(header, tableData); 202 } else if (tag == Tag.post) { 203 return PostScriptTable.Builder.createBuilder(header, tableData); 204 } else if (tag == Tag.cvt) { 205 return ControlValueTable.Builder.createBuilder(header, tableData); 206 // } else if (tag == Tag.fpgm) { 207 // break; 208 } else if (tag == Tag.glyf) { 209 return GlyphTable.Builder.createBuilder(header, tableData); 210 } else if (tag == Tag.loca) { 211 return LocaTable.Builder.createBuilder(header, tableData); 212 } else if (tag == Tag.prep) { 213 return ControlProgramTable.Builder.createBuilder(header, tableData); 214 // } else if (tag == CFF) { 215 // break; 216 // } else if (tag == VORG) { 217 // break; 218 } else if (tag == Tag.EBDT) { 219 return EbdtTable.Builder.createBuilder(header, tableData); 220 } else if (tag == Tag.EBLC) { 221 return EblcTable.Builder.createBuilder(header, tableData); 222 } else if (tag == Tag.EBSC) { 223 return EbscTable.Builder.createBuilder(header, tableData); 224 // } else if (tag == BASE) { 225 // break; 226 // } else if (tag == GDEF) { 227 // break; 228 // } else if (tag == GPOS) { 229 // break; 230 } else if (tag == Tag.GSUB) { 231 return GSubTable.Builder.createBuilder(header, tableData); 232 // break; 233 // } else if (tag == JSTF) { 234 // break; 235 // } else if (tag == DSIG) { 236 // break; 237 // } else if (tag == gasp) { 238 // break; 239 } else if (tag == Tag.hdmx) { 240 return HorizontalDeviceMetricsTable.Builder.createBuilder(header, tableData); 241 // break; 242 // } else if (tag == kern) { 243 // break; 244 // } else if (tag == LTSH) { 245 // break; 246 // } else if (tag == PCLT) { 247 // break; 248 // } else if (tag == VDMX) { 249 // break; 250 // } else if (tag == vhea) { 251 // break; 252 // } else if (tag == vmtx) { 253 // break; 254 } else if (tag == Tag.bhed) { 255 return FontHeaderTable.Builder.createBuilder(header, tableData); 256 } else if (tag == Tag.bdat) { 257 return EbdtTable.Builder.createBuilder(header, tableData); 258 } else if (tag == Tag.bloc) { 259 return EblcTable.Builder.createBuilder(header, tableData); 260 } 261 return GenericTableBuilder.createBuilder(header, tableData); 262 } 263 } 264 } 265