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
23namespace sfntly {
24
25class WritableFontData;
26class 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
48class 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};
304typedef Ptr<ReadableFontData> ReadableFontDataPtr;
305
306}  // namespace sfntly
307
308#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
309