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