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_TABLE_TRUETYPE_GLYPH_TABLE_H_
18 #define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
19 
20 #include <vector>
21 
22 #include "sfntly/table/table.h"
23 #include "sfntly/table/subtable.h"
24 #include "sfntly/table/subtable_container_table.h"
25 
26 namespace sfntly {
27 
28 struct GlyphType {
29   enum {
30     kSimple = 0,
31     kComposite = 1
32   };
33 };
34 
35 class GlyphTable : public SubTableContainerTable,
36                    public RefCounted<GlyphTable> {
37  public:
38   class Builder;
39   class Glyph : public SubTable {
40    public:
41     // Note: Contour is an empty class for the version ported
42     class Contour {
43      protected:
Contour()44       Contour() {}
~Contour()45       virtual ~Contour() {}
46     };
47 
48     class Builder : public SubTable::Builder {
49      public:
50       virtual ~Builder();
51 
52      protected:
53       // Incoming table_builder is GlyphTable::Builder*.
54       // Note: constructor refactored in C++ to avoid heavy lifting.
55       //       caller need to do data->Slice(offset, length) beforehand.
56       explicit Builder(WritableFontData* data);
57       explicit Builder(ReadableFontData* data);
58 
59       static CALLER_ATTACH Builder*
60           GetBuilder(GlyphTable::Builder* table_builder,
61                      ReadableFontData* data);
62       static CALLER_ATTACH Builder*
63           GetBuilder(GlyphTable::Builder* table_builder,
64                      ReadableFontData* data,
65                      int32_t offset,
66                      int32_t length);
67       virtual void SubDataSet();
68       virtual int32_t SubDataSizeToSerialize();
69       virtual bool SubReadyToSerialize();
70       virtual int32_t SubSerialize(WritableFontData* new_data);
71 
72      private:
73       friend class GlyphTable::Builder;
74     };
75 
76     virtual ~Glyph();
77     static CALLER_ATTACH Glyph* GetGlyph(GlyphTable* table,
78                                          ReadableFontData* data,
79                                          int32_t offset,
80                                          int32_t length);
81 
82     virtual int32_t Padding();
83     virtual int32_t GlyphType();
84     virtual int32_t NumberOfContours();
85     virtual int32_t XMin();
86     virtual int32_t XMax();
87     virtual int32_t YMin();
88     virtual int32_t YMax();
89 
90     virtual int32_t InstructionSize() = 0;
91     virtual ReadableFontData* Instructions() = 0;
92 
93    protected:
94     // Note: constructor refactored in C++ to avoid heavy lifting.
95     //       caller need to do data->Slice(offset, length) beforehand.
96     Glyph(ReadableFontData* data, int32_t glyph_type);
97     virtual void Initialize() = 0;
98     // Note: Derived class to define initialization_lock_.
99 
100    private:
101     static int32_t GlyphType(ReadableFontData* data,
102                              int32_t offset,
103                              int32_t length);
104 
105     int32_t glyph_type_;
106     int32_t number_of_contours_;
107   };  // class GlyphTable::Glyph
108   typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
109   typedef std::vector<GlyphBuilderPtr> GlyphBuilderList;
110 
111   class Builder : public SubTableContainerTable::Builder,
112                   public RefCounted<GlyphTable::Builder> {
113    public:
114     // Note: Constructor scope altered to public for base class to instantiate.
115     Builder(Header* header, ReadableFontData* data);
116     virtual ~Builder();
117 
118     virtual void SetLoca(const IntegerList& loca);
119     virtual void GenerateLocaList(IntegerList* locas);
120 
121     static CALLER_ATTACH Builder* CreateBuilder(Header* header,
122                                                 WritableFontData* data);
123 
124     // Gets the List of glyph builders for the glyph table builder. These may be
125     // manipulated in any way by the caller and the changes will be reflected in
126     // the final glyph table produced.
127     // If there is no current data for the glyph builder or the glyph builders
128     // have not been previously set then this will return an empty glyph builder
129     // List. If there is current data (i.e. data read from an existing font) and
130     // the <code>loca</code> list has not been set or is null, empty, or
131     // invalid, then an empty glyph builder List will be returned.
132     GlyphBuilderList* GlyphBuilders();
133 
134     // Replace the internal glyph builders with the one provided. The provided
135     // list and all contained objects belong to this builder.
136     // This call is only required if the entire set of glyphs in the glyph
137     // table builder are being replaced. If the glyph builder list provided from
138     // the GlyphTable.Builder::GlyphBuilders() is being used and modified
139     // then those changes will already be reflected in the glyph table builder.
140     void SetGlyphBuilders(GlyphBuilderList* glyph_builders);
141 
142     // Glyph builder factories
143     CALLER_ATTACH Glyph::Builder* GlyphBuilder(ReadableFontData* data);
144 
145    protected:  // internal API for building
146     virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
147     virtual void SubDataSet();
148     virtual int32_t SubDataSizeToSerialize();
149     virtual bool SubReadyToSerialize();
150     virtual int32_t SubSerialize(WritableFontData* new_data);
151 
152    private:
153     void Initialize(ReadableFontData* data, const IntegerList& loca);
154     GlyphBuilderList* GetGlyphBuilders();
155     void Revert();
156 
157     GlyphBuilderList glyph_builders_;
158     IntegerList loca_;
159   };
160 
161   class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
162    public:
163     static const int32_t kFLAG_ONCURVE;
164     static const int32_t kFLAG_XSHORT;
165     static const int32_t kFLAG_YSHORT;
166     static const int32_t kFLAG_REPEAT;
167     static const int32_t kFLAG_XREPEATSIGN;
168     static const int32_t kFLAG_YREPEATSIGN;
169 
170     class SimpleContour : public Glyph::Contour {
171      protected:
SimpleContour()172       SimpleContour() {}
~SimpleContour()173       virtual ~SimpleContour() {}
174     };
175 
176     class SimpleGlyphBuilder : public Glyph::Builder,
177                                public RefCounted<SimpleGlyphBuilder> {
178      public:
179       virtual ~SimpleGlyphBuilder();
180 
181      protected:
182       // Note: constructor refactored in C++ to avoid heavy lifting.
183       //       caller need to do data->Slice(offset, length) beforehand.
184       explicit SimpleGlyphBuilder(WritableFontData* data);
185       explicit SimpleGlyphBuilder(ReadableFontData* data);
186       virtual CALLER_ATTACH FontDataTable*
187           SubBuildTable(ReadableFontData* data);
188 
189      private:
190       friend class Glyph::Builder;
191     };
192 
193     // Note: constructor refactored in C++ to avoid heavy lifting.
194     //       caller need to do data->Slice(offset, length) beforehand.
195     explicit SimpleGlyph(ReadableFontData* data);
196     virtual ~SimpleGlyph();
197 
198     virtual int32_t InstructionSize();
199     virtual CALLER_ATTACH ReadableFontData* Instructions();
200     virtual void Initialize();
201 
202     int32_t NumberOfPoints(int32_t contour);
203     int32_t XCoordinate(int32_t contour, int32_t point);
204     int32_t YCoordinate(int32_t contour, int32_t point);
205     bool OnCurve(int32_t contour, int32_t point);
206 
207    private:
208     void ParseData(bool fill_arrays);
209     int32_t FlagAsInt(int32_t index);
210     int32_t ContourEndPoint(int32_t contour);
211 
212     bool initialized_;
213     Lock initialization_lock_;
214     int32_t instruction_size_;
215     int32_t number_of_points_;
216 
217     // start offsets of the arrays
218     int32_t instructions_offset_;
219     int32_t flags_offset_;
220     int32_t x_coordinates_offset_;
221     int32_t y_coordinates_offset_;
222 
223     int32_t flag_byte_count_;
224     int32_t x_byte_count_;
225     int32_t y_byte_count_;
226 
227     IntegerList x_coordinates_;
228     IntegerList y_coordinates_;
229     std::vector<bool> on_curve_;
230     IntegerList contour_index_;
231   };
232 
233   class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
234    public:
235     static const int32_t kFLAG_ARG_1_AND_2_ARE_WORDS;
236     static const int32_t kFLAG_ARGS_ARE_XY_VALUES;
237     static const int32_t kFLAG_ROUND_XY_TO_GRID;
238     static const int32_t kFLAG_WE_HAVE_A_SCALE;
239     static const int32_t kFLAG_RESERVED;
240     static const int32_t kFLAG_MORE_COMPONENTS;
241     static const int32_t kFLAG_WE_HAVE_AN_X_AND_Y_SCALE;
242     static const int32_t kFLAG_WE_HAVE_A_TWO_BY_TWO;
243     static const int32_t kFLAG_WE_HAVE_INSTRUCTIONS;
244     static const int32_t kFLAG_USE_MY_METRICS;
245     static const int32_t kFLAG_OVERLAP_COMPOUND;
246     static const int32_t kFLAG_SCALED_COMPONENT_OFFSET;
247     static const int32_t kFLAG_UNSCALED_COMPONENT_OFFSET;
248 
249     class CompositeGlyphBuilder : public Glyph::Builder,
250                                   public RefCounted<CompositeGlyphBuilder> {
251      public:
252       virtual ~CompositeGlyphBuilder();
253 
254      protected:
255       // Note: constructor refactored in C++ to avoid heavy lifting.
256       //       caller need to do data->Slice(offset, length) beforehand.
257       explicit CompositeGlyphBuilder(WritableFontData* data);
258       explicit CompositeGlyphBuilder(ReadableFontData* data);
259 
260       virtual CALLER_ATTACH FontDataTable*
261           SubBuildTable(ReadableFontData* data);
262 
263      private:
264       friend class Glyph::Builder;
265     };
266 
267     // Note: constructor refactored in C++ to avoid heavy lifting.
268     //       caller need to do data->Slice(offset, length) beforehand.
269     explicit CompositeGlyph(ReadableFontData* data);
270     virtual ~CompositeGlyph();
271 
272     int32_t Flags(int32_t contour);
273     int32_t NumGlyphs();
274     int32_t GlyphIndex(int32_t contour);
275     int32_t Argument1(int32_t contour);
276     int32_t Argument2(int32_t contour);
277     int32_t TransformationSize(int32_t contour);
278     void Transformation(int32_t contour, ByteVector* transformation);
279     virtual int32_t InstructionSize();
280     virtual CALLER_ATTACH ReadableFontData* Instructions();
281 
282    protected:
283     virtual void Initialize();
284 
285    private:
286     IntegerList contour_index_;
287     int32_t instruction_size_;
288     int32_t instructions_offset_;
289     bool initialized_;
290     Lock initialization_lock_;
291   };
292 
293   virtual ~GlyphTable();
294 
295   // C++ port: rename glyph() to GetGlyph().
296   Glyph* GetGlyph(int32_t offset, int32_t length);
297 
298  private:
299   struct Offset {
300     enum {
301       // header
302       kNumberOfContours = 0,
303       kXMin = 2,
304       kYMin = 4,
305       kXMax = 6,
306       kYMax = 8,
307 
308       // Simple Glyph Description
309       kSimpleEndPtsOfCountours = 10,
310       // offset from the end of the contours array
311       kSimpleInstructionLength = 0,
312       kSimpleInstructions = 2,
313       // flags
314       // xCoordinates
315       // yCoordinates
316 
317       // Composite Glyph Description
318       kCompositeFlags = 0,
319       kCompositeGyphIndexWithoutFlag = 0,
320       kCompositeGlyphIndexWithFlag = 2,
321     };
322   };
323 
324   GlyphTable(Header* header, ReadableFontData* data);
325 };
326 typedef Ptr<GlyphTable> GlyphTablePtr;
327 typedef Ptr<GlyphTable::Builder> GlyphTableBuilderPtr;
328 typedef std::vector<GlyphTableBuilderPtr> GlyphTableBuilderList;
329 typedef Ptr<GlyphTable::Glyph> GlyphPtr;
330 typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
331 
332 }  // namespace sfntly
333 
334 #endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
335