1 /* 2 * Copyright 2011 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 21 import java.util.Comparator; 22 23 /** 24 * The header entry for a table in the OffsetTable for the font. 25 * 26 * For equality purposes the only property of the header that is considered is 27 * the tag - the name of the table that is referred to by this header. There can 28 * only be one table with each tag in the font and it doesn't matter what the 29 * other properties of that header are for that purpose. 30 * 31 * @author Stuart Gill 32 * 33 */ 34 public final class Header { 35 private final int tag; 36 private final int offset; 37 private final boolean offsetValid; 38 private final int length; 39 private final boolean lengthValid; 40 private final long checksum; 41 private final boolean checksumValid; 42 43 public static final Comparator<Header> COMPARATOR_BY_OFFSET = new Comparator<Header>() { 44 @Override 45 public int compare(Header h1, Header h2) { 46 return h1.offset - h2.offset; 47 } 48 }; 49 50 public static final Comparator<Header> COMPARATOR_BY_TAG = new Comparator<Header>() { 51 @Override 52 public int compare(Header h1, Header h2) { 53 return h1.tag - h2.tag; 54 } 55 }; 56 57 /** 58 * Constructor. 59 * 60 * Make a full header as read from an existing font. 61 * 62 * @param tag 63 * @param offset 64 * @param length 65 * @param checksum 66 */ Header(int tag, long checksum, int offset, int length)67 public Header(int tag, long checksum, int offset, int length) { 68 this.tag = tag; 69 this.checksum = checksum; 70 this.checksumValid = true; 71 this.offset = offset; 72 this.offsetValid = true; 73 this.length = length; 74 this.lengthValid = true; 75 } 76 77 /** 78 * Constructor. 79 * 80 * Make a partial header with only the basic info for a new table. 81 * 82 * @param tag 83 * @param length 84 */ Header(int tag, int length)85 public Header(int tag, int length) { 86 this.tag = tag; 87 this.checksum = 0; 88 this.checksumValid = false; 89 this.offset = 0; 90 this.offsetValid = false; 91 this.length = length; 92 this.lengthValid = true; 93 } 94 95 /** 96 * Constructor. 97 * 98 * Make a partial header with only the basic info for an empty new table. 99 * 100 * @param tag 101 */ Header(int tag)102 public Header(int tag) { 103 this.tag = tag; 104 this.checksum = 0; 105 this.checksumValid = false; 106 this.offset = 0; 107 this.offsetValid = false; 108 this.length = 0; 109 this.lengthValid = true; 110 } 111 112 /** 113 * Get the table tag. 114 * 115 * @return the tag 116 */ tag()117 public int tag() { 118 return tag; 119 } 120 121 /** 122 * Get the table offset. The offset is from the start of the font file. This 123 * offset value is what was read from the font file during construction of the 124 * font. It may not be meaningful if the font was maninpulated through the 125 * builders. 126 * 127 * @return the offset 128 */ offset()129 public int offset() { 130 return offset; 131 } 132 133 /** 134 * Is the offset in the header valid. The offset will not be valid if the 135 * table was constructed during building and has no physical location in a 136 * font file. 137 * 138 * @return true if the offset is valid; false otherwise 139 */ offsetValid()140 public boolean offsetValid() { 141 return offsetValid; 142 } 143 144 /** 145 * Get the length of the table as recorded in the table record header. During 146 * building the header length will reflect the length that was initially read 147 * from the font file. This may not be consistent with the current state of 148 * the data. 149 * 150 * @return the length 151 */ length()152 public int length() { 153 return length; 154 } 155 156 /** 157 * Is the length in the header valid. The length will not be valid if the 158 * table was constructed during building and has no physical location in a 159 * font file until the table is built from the builder. 160 * 161 * @return true if the offset is valid; false otherwise 162 */ lengthValid()163 public boolean lengthValid() { 164 return lengthValid; 165 } 166 167 /** 168 * Get the checksum for the table as recorded in the table record header. 169 * 170 * @return the checksum 171 */ checksum()172 public long checksum() { 173 return checksum; 174 } 175 176 /** 177 * Is the checksum valid. The checksum will not be valid if the table was 178 * constructed during building and has no physical location in a font file. 179 * Note that this does <b>not</b> check the validity of the checksum against 180 * the calculated checksum for the table data. 181 * 182 * @return true if the checksum is valid; false otherwise 183 */ checksumValid()184 public boolean checksumValid() { 185 return checksumValid; 186 } 187 188 /** 189 * Checks equality of this Header against another object. The only property of 190 * the Header object that is considered is the tag. 191 */ 192 @Override equals(Object obj)193 public boolean equals(Object obj) { 194 if (!(obj instanceof Header)) { 195 return false; 196 } 197 return ((Header) obj).tag == this.tag; 198 } 199 200 /** 201 * Computes the hashcode for this Header . The only property of the Header 202 * object that is considered is the tag. 203 */ 204 @Override hashCode()205 public int hashCode() { 206 return this.tag; 207 } 208 209 @Override toString()210 public String toString() { 211 StringBuilder builder = new StringBuilder(); 212 builder.append("["); 213 builder.append(Tag.stringValue(this.tag)); 214 builder.append(", "); 215 builder.append(Long.toHexString(this.checksum)); 216 builder.append(", "); 217 builder.append(Integer.toHexString(this.offset)); 218 builder.append(", "); 219 builder.append(Integer.toHexString(this.length)); 220 builder.append("]"); 221 return builder.toString(); 222 } 223 }