readable_font_data.h revision 584bf6606b53bda8bf0810e7c0ad57e24cacb4f1
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/port/refcount.h"
21#include "sfntly/data/font_data.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 LONG at the given index.
132  // @param index index into the font data
133  // @return the LONG
134  // @throws IndexOutOfBoundsException if index is outside the FontData's range
135  virtual int32_t ReadLong(int32_t index);
136
137  // Read the Fixed at the given index.
138  // @param index index into the font data
139  // @return the Fixed
140  // @throws IndexOutOfBoundsException if index is outside the FontData's range
141  virtual int32_t ReadFixed(int32_t index);
142
143  // Read the LONGDATETIME at the given index.
144  // @param index index into the font data
145  // @return the LONGDATETIME
146  // @throws IndexOutOfBoundsException if index is outside the FontData's range
147  virtual int64_t ReadDateTimeAsLong(int32_t index);
148
149  // Read the FWORD at the given index.
150  // @param index index into the font data
151  // @return the FWORD
152  // @throws IndexOutOfBoundsException if index is outside the FontData's range
153  virtual int32_t ReadFWord(int32_t index);
154
155  // Read the UFWORD at the given index.
156  // @param index index into the font data
157  // @return the UFWORD
158  // @throws IndexOutOfBoundsException if index is outside the FontData's range
159  virtual int32_t ReadFUFWord(int32_t index);
160
161  // Note: Not ported because they just throw UnsupportedOperationException()
162  //       in Java.
163  /*
164  virtual int32_t ReadFUnit(int32_t index);
165  virtual int64_t ReadF2Dot14(int32_t index);
166  */
167
168  // Copy the FontData to an OutputStream.
169  // @param os the destination
170  // @return number of bytes copied
171  // @throws IOException
172  virtual int32_t CopyTo(OutputStream* os);
173
174  // Copy the FontData to a WritableFontData.
175  // @param wfd the destination
176  // @return number of bytes copied
177  // @throws IOException
178  virtual int32_t CopyTo(WritableFontData* wfd);
179
180  // Make gcc -Woverloaded-virtual happy.
181  virtual int32_t CopyTo(ByteArray* ba);
182
183  // Search for the key value in the range tables provided.
184  //
185  //  The search looks through the start-end pairs looking for the key value. It
186  // is assumed that the start-end pairs are both represented by UShort values,
187  // ranges do not overlap, and are monotonically increasing.
188  //
189  // @param startIndex the position to read the first start value from
190  // @param startOffset the offset between subsequent start values
191  // @param endIndex the position to read the first end value from
192  // @param endOffset the offset between subsequent end values
193  // @param length the number of start-end pairs
194  // @param key the value to search for
195  // @return the index of the start-end pairs in which the key was found; -1
196  //         otherwise
197  int32_t SearchUShort(int32_t start_index,
198                       int32_t start_offset,
199                       int32_t end_index,
200                       int32_t end_offset,
201                       int32_t length,
202                       int32_t key);
203
204  // Search for the key value in the range tables provided.
205  //
206  // The search looks through the start-end pairs looking for the key value. It
207  // is assumed that the start-end pairs are both represented by ULong values
208  // that can be represented within 31 bits, ranges do not overlap, and are
209  // monotonically increasing.
210  //
211  // @param startIndex the position to read the first start value from
212  // @param startOffset the offset between subsequent start values
213  // @param endIndex the position to read the first end value from
214  // @param endOffset the offset between subsequent end values
215  // @param length the number of start-end pairs
216  // @param key the value to search for
217  // @return the index of the start-end pairs in which the key was found; -1
218  //         otherwise
219  int32_t SearchULong(int32_t start_index,
220                      int32_t start_offset,
221                      int32_t end_index,
222                      int32_t end_offset,
223                      int32_t length,
224                      int32_t key);
225
226
227  // TODO(arthurhsu): IMPLEMENT
228  /*
229  virtual int32_t ReadFUnit(int32_t index);
230  virtual int64_t ReadF2Dot14(int32_t index);
231  virtual int64_t ReadLongDateTime(int32_t index);
232  */
233
234  // Makes a slice of this FontData. The returned slice will share the data with
235  // the original FontData.
236  // @param offset the start of the slice
237  // @param length the number of bytes in the slice
238  // @return a slice of the original FontData
239  // Note: C++ polymorphism requires return type to be consistent
240  virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
241
242  // Makes a bottom bound only slice of this array. The returned slice will
243  // share the data with the original FontData.
244  // @param offset the start of the slice
245  // @return a slice of the original FontData
246  // Note: C++ polymorphism requires return type to be consistent
247  virtual CALLER_ATTACH FontData* Slice(int32_t offset);
248
249  // Not Ported: toString()
250
251 protected:
252  // Constructor. Creates a bounded wrapper of another ReadableFontData from the
253  // given offset until the end of the original ReadableFontData.
254  // @param data data to wrap
255  // @param offset the start of this data's view of the original data
256  ReadableFontData(ReadableFontData* data, int32_t offset);
257
258  // Constructor. Creates a bounded wrapper of another ReadableFontData from the
259  // given offset until the end of the original ReadableFontData.
260  // @param data data to wrap
261  // @param offset the start of this data's view of the original data
262  // @param length the length of the other FontData to use
263  ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length);
264
265 private:
266  // Compute the checksum for the font data using any ranges set for the
267  // calculation.
268  void ComputeChecksum();
269
270  // Do the actual computation of the checksum for a range using the
271  // TrueType/OpenType checksum algorithm. The range used is from the low bound
272  // to the high bound in steps of four bytes. If any of the bytes within that 4
273  // byte segment are not readable then it will considered a zero for
274  // calculation.
275  // Only called from within a synchronized method so it does not need to be
276  // synchronized itself.
277  // @param lowBound first position to start a 4 byte segment on
278  // @param highBound last possible position to start a 4 byte segment on
279  // @return the checksum for the total range
280  int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound);
281
282  bool checksum_set_;  // TODO(arthurhsu): IMPLEMENT: must be set atomically.
283  int64_t checksum_;
284  IntegerList checksum_range_;
285};
286typedef Ptr<ReadableFontData> ReadableFontDataPtr;
287
288}  // namespace sfntly
289
290#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
291