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