summaryrefslogtreecommitdiff
path: root/sfntly/glyph_table.h
blob: c066d4730e24fa9322f8853212e870819810e84c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_GLYPH_TABLE_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_GLYPH_TABLE_H_

#include <vector>

#include "sfntly/table.h"
#include "sfntly/subtable.h"

namespace sfntly {

struct GlyphType {
  enum {
    kSimple = 0,
    kComposite = 1
  };
};

// Note: due to the complexity of this class, the order of declaration is
//       different from its Java counter part.  GlyphTable::Glyph is defined
//       before GlyphTable::Builder to avoid compilation errors.
class GlyphTable : public Table, public RefCounted<GlyphTable> {
 public:
  class Builder;
  class Glyph : public SubTable {
   public:
    // Note: Contour is an empty class for the version ported
    class Contour {
     protected:
      Contour() {}
      virtual ~Contour() {}
    };

    class Builder : public SubTable::Builder {
     public:
      virtual ~Builder();

     protected:
      // Incoming table_builder is GlyphTable::Builder*.
      // Note: constructor refactored in C++ to avoid heavy lifting.
      //       caller need to do data->Slice(offset, length) beforehand.
      Builder(FontDataTableBuilderContainer* table_builder,
              WritableFontData* data);
      Builder(FontDataTableBuilderContainer* table_builder,
              ReadableFontData* data);

      static CALLER_ATTACH Builder*
          GetBuilder(FontDataTableBuilderContainer* table_builder,
                     ReadableFontData* data);
      static CALLER_ATTACH Builder*
          GetBuilder(FontDataTableBuilderContainer* table_builder,
                     ReadableFontData* data,
                     int32_t offset,
                     int32_t length);
      virtual void SubDataSet();
      virtual int32_t SubDataSizeToSerialize();
      virtual bool SubReadyToSerialize();
      virtual int32_t SubSerialize(WritableFontData* new_data);

     private:
      int32_t format_;
      friend class GlyphTable::Builder;
    };

    virtual ~Glyph();
    static CALLER_ATTACH Glyph* GetGlyph(ReadableFontData* data,
                                         int32_t offset,
                                         int32_t length);
    virtual int32_t GlyphType();
    virtual int32_t NumberOfContours();
    virtual int32_t XMin();
    virtual int32_t XMax();
    virtual int32_t YMin();
    virtual int32_t YMax();
    virtual int32_t Padding();  // override FontDataTable::Padding()

    virtual int32_t InstructionSize() = 0;
    virtual ReadableFontData* Instructions() = 0;

   protected:
    // Note: constructor refactored in C++ to avoid heavy lifting.
    //       caller need to do data->Slice(offset, length) beforehand.
    Glyph(ReadableFontData* data, int32_t glyph_type);

    // TODO(arthurhsu): violating C++ style guide, need refactoring.
    int32_t padding_;

   private:
    static int32_t GlyphType(ReadableFontData* data,
                             int32_t offset,
                             int32_t length);

    int32_t glyph_type_;
    int32_t number_of_contours_;
  };  // class GlyphTable::Glyph
  typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
  typedef std::vector<GlyphBuilderPtr> GlyphBuilderList;

  class Builder : public Table::ArrayElementTableBuilder,
                  public RefCounted<GlyphTable::Builder> {
   public:
    // Note: Constructor scope altered to public for base class to instantiate.
    Builder(FontDataTableBuilderContainer* font_builder,
            Header* header,
            WritableFontData* data);
    virtual ~Builder();

    virtual void SetLoca(const IntegerList& loca);
    virtual void GenerateLocaList(IntegerList* locas);

    // Gets the List of glyph builders for the glyph table builder. These may be
    // manipulated in any way by the caller and the changes will be reflected in
    // the final glyph table produced.
    // If there is no current data for the glyph builder or the glyph builders
    // have not been previously set then this will return an empty glyph builder
    // List. If there is current data (i.e. data read from an existing font) and
    // the <code>loca</code> list has not been set or is null, empty, or
    // invalid, then an empty glyph builder List will be returned.
    GlyphBuilderList* GlyphBuilders();

    // Replace the internal glyph builders with the one provided.
    void SetGlyphBuilders(GlyphBuilderList* glyph_builders);

    // Glyph builder factories
    CALLER_ATTACH Glyph::Builder* GlyphBuilder(ReadableFontData* data);

   protected:  // internal API for building
    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
    virtual void SubDataSet();
    virtual int32_t SubDataSizeToSerialize();
    virtual bool SubReadyToSerialize();
    virtual int32_t SubSerialize(WritableFontData* new_data);

   private:
    void Initialize(ReadableFontData* data, const IntegerList& loca);
    GlyphBuilderList* GetGlyphBuilders();
    void Revert();

    GlyphBuilderList glyph_builders_;
    IntegerList loca_;
  };

  class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
   public:
    static const int32_t kFLAG_ONCURVE;
    static const int32_t kFLAG_XSHORT;
    static const int32_t kFLAG_YSHORT;
    static const int32_t kFLAG_REPEAT;
    static const int32_t kFLAG_XREPEATSIGN;
    static const int32_t kFLAG_YREPEATSIGN;

    class SimpleContour : public Glyph::Contour {
     protected:
      SimpleContour() {}
      virtual ~SimpleContour() {}
    };

    class SimpleGlyphBuilder : public Glyph::Builder,
                               public RefCounted<SimpleGlyphBuilder> {
     public:
      virtual ~SimpleGlyphBuilder();

     protected:
      // Note: constructor refactored in C++ to avoid heavy lifting.
      //       caller need to do data->Slice(offset, length) beforehand.
      SimpleGlyphBuilder(FontDataTableBuilderContainer* table_builder,
                         WritableFontData* data);
      SimpleGlyphBuilder(FontDataTableBuilderContainer* table_builder,
                         ReadableFontData* data);
      virtual CALLER_ATTACH FontDataTable*
          SubBuildTable(ReadableFontData* data);

     private:
      friend class Glyph::Builder;
    };

    // Note: constructor refactored in C++ to avoid heavy lifting.
    //       caller need to do data->Slice(offset, length) beforehand.
    explicit SimpleGlyph(ReadableFontData* data);
    virtual ~SimpleGlyph();

    virtual int32_t InstructionSize();
    virtual CALLER_ATTACH ReadableFontData* Instructions();
    int32_t NumberOfPoints(int32_t contour);
    int32_t XCoordinate(int32_t contour, int32_t point);
    int32_t YCoordinate(int32_t contour, int32_t point);
    bool OnCurve(int32_t contour, int32_t point);

   private:
    void Initialize();
    void ParseData(bool fill_arrays);
    int32_t FlagAsInt(int32_t index);
    int32_t ContourEndPoint(int32_t contour);

    bool initialized_;
    int32_t instruction_size_;
    int32_t number_of_points_;

    // start offsets of the arrays
    int32_t instructions_offset_;
    int32_t flags_offset_;
    int32_t x_coordinates_offset_;
    int32_t y_coordinates_offset_;

    int32_t flag_byte_count_;
    int32_t x_byte_count_;
    int32_t y_byte_count_;

    IntegerList x_coordinates_;
    IntegerList y_coordinates_;
    std::vector<bool> on_curve_;
    IntegerList contour_index_;
  };

  class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
   public:
    static const int32_t kFLAG_ARG_1_AND_2_ARE_WORDS;
    static const int32_t kFLAG_ARGS_ARE_XY_VALUES;
    static const int32_t kFLAG_ROUND_XY_TO_GRID;
    static const int32_t kFLAG_WE_HAVE_A_SCALE;
    static const int32_t kFLAG_RESERVED;
    static const int32_t kFLAG_MORE_COMPONENTS;
    static const int32_t kFLAG_WE_HAVE_AN_X_AND_Y_SCALE;
    static const int32_t kFLAG_WE_HAVE_A_TWO_BY_TWO;
    static const int32_t kFLAG_WE_HAVE_INSTRUCTIONS;
    static const int32_t kFLAG_USE_MY_METRICS;
    static const int32_t kFLAG_OVERLAP_COMPOUND;
    static const int32_t kFLAG_SCALED_COMPONENT_OFFSET;
    static const int32_t kFLAG_UNSCALED_COMPONENT_OFFSET;

    class CompositeGlyphBuilder : public Glyph::Builder,
                                  public RefCounted<CompositeGlyphBuilder> {
     public:
      virtual ~CompositeGlyphBuilder();

     protected:
      // Note: constructor refactored in C++ to avoid heavy lifting.
      //       caller need to do data->Slice(offset, length) beforehand.
      CompositeGlyphBuilder(FontDataTableBuilderContainer* table_builder,
                            WritableFontData* data);
      CompositeGlyphBuilder(FontDataTableBuilderContainer* table_builder,
                            ReadableFontData* data);

      virtual CALLER_ATTACH FontDataTable*
          SubBuildTable(ReadableFontData* data);

     private:
      friend class Glyph::Builder;
    };

    // Note: constructor refactored in C++ to avoid heavy lifting.
    //       caller need to do data->Slice(offset, length) beforehand.
    explicit CompositeGlyph(ReadableFontData* data);
    virtual ~CompositeGlyph();

    int32_t Flags(int32_t contour);
    int32_t NumGlyphs();
    int32_t GlyphIndex(int32_t contour);
    int32_t Argument1(int32_t contour);
    int32_t Argument2(int32_t contour);
    int32_t TransformationSize(int32_t contour);
    void Transformation(int32_t contour, ByteVector* transformation);
    virtual int32_t InstructionSize();
    virtual CALLER_ATTACH ReadableFontData* Instructions();

   private:
    void ParseData();

    IntegerList contour_index_;
    int32_t instruction_size_;
    int32_t instructions_offset_;
  };

  virtual ~GlyphTable();

  // C++ port: rename glyph() to GetGlyph().
  Glyph* GetGlyph(int32_t offset, int32_t length);

 private:
  struct Offset {
    enum {
      // header
      kNumberOfContours = 0,
      kXMin = 2,
      kYMin = 4,
      kXMax = 6,
      kYMax = 8,

      // Simple Glyph Description
      kSimpleEndPtsOfCountours = 10,
      // offset from the end of the contours array
      kSimpleInstructionLength = 0,
      kSimpleInstructions = 2,
      // flags
      // xCoordinates
      // yCoordinates

      // Composite Glyph Description
      kCompositeFlags = 0,
      kCompositeGyphIndexWithoutFlag = 0,
      kCompositeGlyphIndexWithFlag = 2,
    };
  };

  GlyphTable(Header* header, ReadableFontData* data);
};
typedef Ptr<GlyphTable> GlyphTablePtr;
typedef Ptr<GlyphTable::Builder> GlyphTableBuilderPtr;
typedef std::vector<GlyphTableBuilderPtr> GlyphTableBuilderList;
typedef Ptr<GlyphTable::Glyph> GlyphPtr;
typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;

}  // namespace sfntly

#endif  // TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_GLYPH_TABLE_H_