Home | History | Annotate | Download | only in data
      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