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 #ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_ 18 #define SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_ 19 20 #include "sfntly/data/font_data.h" 21 #include "sfntly/port/lock.h" 22 23 namespace sfntly { 24 25 class WritableFontData; 26 class OutputStream; 27 28 // Writable font data wrapper. Supports reading of data primitives in the 29 // TrueType / OpenType spec. 30 // The data types used are as listed: 31 // BYTE 8-bit unsigned integer. 32 // CHAR 8-bit signed integer. 33 // USHORT 16-bit unsigned integer. 34 // SHORT 16-bit signed integer. 35 // UINT24 24-bit unsigned integer. 36 // ULONG 32-bit unsigned integer. 37 // LONG 32-bit signed integer. 38 // Fixed 32-bit signed fixed-point number (16.16) 39 // FUNIT Smallest measurable distance in the em space. 40 // FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits. 41 // UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in 42 // FUnits. 43 // F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14) 44 // LONGDATETIME Date represented in number of seconds since 12:00 midnight, 45 // January 1, 1904. The value is represented as a signed 64-bit 46 // integer. 47 48 class ReadableFontData : public FontData, 49 public RefCounted<ReadableFontData> { 50 public: 51 explicit ReadableFontData(ByteArray* array); 52 virtual ~ReadableFontData(); 53 54 static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b); 55 56 // Gets a computed checksum for the data. This checksum uses the OpenType spec 57 // calculation. Every ULong value (32 bit unsigned) in the data is summed and 58 // the resulting value is truncated to 32 bits. If the data length in bytes is 59 // not an integral multiple of 4 then any remaining bytes are treated as the 60 // start of a 4 byte sequence whose remaining bytes are zero. 61 // @return the checksum 62 int64_t Checksum(); 63 64 // Sets the bounds to use for computing the checksum. These bounds are in 65 // begin and end pairs. If an odd number is given then the final range is 66 // assumed to extend to the end of the data. The lengths of each range must be 67 // a multiple of 4. 68 // @param ranges the range bounds to use for the checksum 69 void SetCheckSumRanges(const IntegerList& ranges); 70 71 // Read the UBYTE at the given index. 72 // @param index index into the font data 73 // @return the UBYTE; -1 if outside the bounds of the font data 74 // @throws IndexOutOfBoundsException if index is outside the FontData's range 75 virtual int32_t ReadUByte(int32_t index); 76 77 // Read the BYTE at the given index. 78 // @param index index into the font data 79 // @return the BYTE 80 // @throws IndexOutOfBoundsException if index is outside the FontData's range 81 virtual int32_t ReadByte(int32_t index); 82 83 // Read the bytes at the given index into the array. 84 // @param index index into the font data 85 // @param b the destination for the bytes read 86 // @param offset offset in the byte array to place the bytes 87 // @param length the length of bytes to read 88 // @return the number of bytes actually read; -1 if the index is outside the 89 // bounds of the font data 90 virtual int32_t ReadBytes(int32_t index, 91 byte_t* b, 92 int32_t offset, 93 int32_t length); 94 95 // Read the CHAR at the given index. 96 // @param index index into the font data 97 // @return the CHAR 98 // @throws IndexOutOfBoundsException if index is outside the FontData's range 99 virtual int32_t ReadChar(int32_t index); 100 101 // Read the USHORT at the given index. 102 // @param index index into the font data 103 // @return the USHORT 104 // @throws IndexOutOfBoundsException if index is outside the FontData's range 105 virtual int32_t ReadUShort(int32_t index); 106 107 // Read the SHORT at the given index. 108 // @param index index into the font data 109 // @return the SHORT 110 // @throws IndexOutOfBoundsException if index is outside the FontData's range 111 virtual int32_t ReadShort(int32_t index); 112 113 // Read the UINT24 at the given index. 114 // @param index index into the font data 115 // @return the UINT24 116 // @throws IndexOutOfBoundsException if index is outside the FontData's range 117 virtual int32_t ReadUInt24(int32_t index); 118 119 // Read the ULONG at the given index. 120 // @param index index into the font data 121 // @return the ULONG 122 // @throws IndexOutOfBoundsException if index is outside the FontData's range 123 virtual int64_t ReadULong(int32_t index); 124 125 // Read the ULONG at the given index as int32_t. 126 // @param index index into the font data 127 // @return the ULONG 128 // @throws IndexOutOfBoundsException if index is outside the FontData's range 129 virtual int32_t ReadULongAsInt(int32_t index); 130 131 // Read the ULONG at the given index, little-endian variant 132 // @param index index into the font data 133 // @return the ULONG 134 // @throws IndexOutOfBoundsException if index is outside the FontData's range 135 virtual int64_t ReadULongLE(int32_t index); 136 137 // Read the LONG at the given index. 138 // @param index index into the font data 139 // @return the LONG 140 // @throws IndexOutOfBoundsException if index is outside the FontData's range 141 virtual int32_t ReadLong(int32_t index); 142 143 // Read the Fixed at the given index. 144 // @param index index into the font data 145 // @return the Fixed 146 // @throws IndexOutOfBoundsException if index is outside the FontData's range 147 virtual int32_t ReadFixed(int32_t index); 148 149 // Read the LONGDATETIME at the given index. 150 // @param index index into the font data 151 // @return the LONGDATETIME 152 // @throws IndexOutOfBoundsException if index is outside the FontData's range 153 virtual int64_t ReadDateTimeAsLong(int32_t index); 154 155 // Read the FWORD at the given index. 156 // @param index index into the font data 157 // @return the FWORD 158 // @throws IndexOutOfBoundsException if index is outside the FontData's range 159 virtual int32_t ReadFWord(int32_t index); 160 161 // Read the UFWORD at the given index. 162 // @param index index into the font data 163 // @return the UFWORD 164 // @throws IndexOutOfBoundsException if index is outside the FontData's range 165 virtual int32_t ReadFUFWord(int32_t index); 166 167 // Note: Not ported because they just throw UnsupportedOperationException() 168 // in Java. 169 /* 170 virtual int32_t ReadFUnit(int32_t index); 171 virtual int64_t ReadF2Dot14(int32_t index); 172 */ 173 174 // Copy the FontData to an OutputStream. 175 // @param os the destination 176 // @return number of bytes copied 177 // @throws IOException 178 virtual int32_t CopyTo(OutputStream* os); 179 180 // Copy the FontData to a WritableFontData. 181 // @param wfd the destination 182 // @return number of bytes copied 183 // @throws IOException 184 virtual int32_t CopyTo(WritableFontData* wfd); 185 186 // Make gcc -Woverloaded-virtual happy. 187 virtual int32_t CopyTo(ByteArray* ba); 188 189 // Search for the key value in the range tables provided. 190 // The search looks through the start-end pairs looking for the key value. It 191 // is assumed that the start-end pairs are both represented by UShort values, 192 // ranges do not overlap, and are monotonically increasing. 193 // @param startIndex the position to read the first start value from 194 // @param startOffset the offset between subsequent start values 195 // @param endIndex the position to read the first end value from 196 // @param endOffset the offset between subsequent end values 197 // @param length the number of start-end pairs 198 // @param key the value to search for 199 // @return the index of the start-end pairs in which the key was found; -1 200 // otherwise 201 int32_t SearchUShort(int32_t start_index, 202 int32_t start_offset, 203 int32_t end_index, 204 int32_t end_offset, 205 int32_t length, 206 int32_t key); 207 208 // Search for the key value in the table provided. 209 // The search looks through the values looking for the key value. It is 210 // assumed that the are represented by UShort values and are monotonically 211 // increasing. 212 // @param startIndex the position to read the first start value from 213 // @param startOffset the offset between subsequent start values 214 // @param length the number of start-end pairs 215 // @param key the value to search for 216 // @return the index of the start-end pairs in which the key was found; -1 217 // otherwise 218 int32_t SearchUShort(int32_t start_index, 219 int32_t start_offset, 220 int32_t length, 221 int32_t key); 222 223 // Search for the key value in the range tables provided. 224 // The search looks through the start-end pairs looking for the key value. It 225 // is assumed that the start-end pairs are both represented by ULong values 226 // that can be represented within 31 bits, ranges do not overlap, and are 227 // monotonically increasing. 228 // @param startIndex the position to read the first start value from 229 // @param startOffset the offset between subsequent start values 230 // @param endIndex the position to read the first end value from 231 // @param endOffset the offset between subsequent end values 232 // @param length the number of start-end pairs 233 // @param key the value to search for 234 // @return the index of the start-end pairs in which the key was found; -1 235 // otherwise 236 int32_t SearchULong(int32_t start_index, 237 int32_t start_offset, 238 int32_t end_index, 239 int32_t end_offset, 240 int32_t length, 241 int32_t key); 242 243 244 // TODO(arthurhsu): IMPLEMENT 245 /* 246 virtual int32_t ReadFUnit(int32_t index); 247 virtual int64_t ReadF2Dot14(int32_t index); 248 virtual int64_t ReadLongDateTime(int32_t index); 249 */ 250 251 // Makes a slice of this FontData. The returned slice will share the data with 252 // the original FontData. 253 // @param offset the start of the slice 254 // @param length the number of bytes in the slice 255 // @return a slice of the original FontData 256 // Note: C++ polymorphism requires return type to be consistent 257 virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length); 258 259 // Makes a bottom bound only slice of this array. The returned slice will 260 // share the data with the original FontData. 261 // @param offset the start of the slice 262 // @return a slice of the original FontData 263 // Note: C++ polymorphism requires return type to be consistent 264 virtual CALLER_ATTACH FontData* Slice(int32_t offset); 265 266 // Not Ported: toString() 267 268 protected: 269 // Constructor. Creates a bounded wrapper of another ReadableFontData from the 270 // given offset until the end of the original ReadableFontData. 271 // @param data data to wrap 272 // @param offset the start of this data's view of the original data 273 ReadableFontData(ReadableFontData* data, int32_t offset); 274 275 // Constructor. Creates a bounded wrapper of another ReadableFontData from the 276 // given offset until the end of the original ReadableFontData. 277 // @param data data to wrap 278 // @param offset the start of this data's view of the original data 279 // @param length the length of the other FontData to use 280 ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length); 281 282 private: 283 // Compute the checksum for the font data using any ranges set for the 284 // calculation. 285 void ComputeChecksum(); 286 287 // Do the actual computation of the checksum for a range using the 288 // TrueType/OpenType checksum algorithm. The range used is from the low bound 289 // to the high bound in steps of four bytes. If any of the bytes within that 4 290 // byte segment are not readable then it will considered a zero for 291 // calculation. 292 // Only called from within a synchronized method so it does not need to be 293 // synchronized itself. 294 // @param lowBound first position to start a 4 byte segment on 295 // @param highBound last possible position to start a 4 byte segment on 296 // @return the checksum for the total range 297 int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound); 298 299 Lock checksum_lock_; 300 bool checksum_set_; 301 int64_t checksum_; 302 IntegerList checksum_range_; 303 }; 304 typedef Ptr<ReadableFontData> ReadableFontDataPtr; 305 306 } // namespace sfntly 307 308 #endif // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_ 309