diff options
Diffstat (limited to 'sfntly/table/truetype/glyph_table.h')
-rw-r--r-- | sfntly/table/truetype/glyph_table.h | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/sfntly/table/truetype/glyph_table.h b/sfntly/table/truetype/glyph_table.h new file mode 100644 index 0000000..4ffddda --- /dev/null +++ b/sfntly/table/truetype/glyph_table.h @@ -0,0 +1,334 @@ +/* + * 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 SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_ +#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_ + +#include <vector> + +#include "sfntly/table/table.h" +#include "sfntly/table/subtable.h" +#include "sfntly/table/subtable_container_table.h" + +namespace sfntly { + +struct GlyphType { + enum { + kSimple = 0, + kComposite = 1 + }; +}; + +class GlyphTable : public SubTableContainerTable, + 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. + explicit Builder(WritableFontData* data); + explicit Builder(ReadableFontData* data); + + static CALLER_ATTACH Builder* + GetBuilder(GlyphTable::Builder* table_builder, + ReadableFontData* data); + static CALLER_ATTACH Builder* + GetBuilder(GlyphTable::Builder* 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: + friend class GlyphTable::Builder; + }; + + virtual ~Glyph(); + static CALLER_ATTACH Glyph* GetGlyph(GlyphTable* table, + ReadableFontData* data, + int32_t offset, + int32_t length); + + virtual int32_t Padding(); + 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 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); + virtual void Initialize() = 0; + // Note: Derived class to define initialization_lock_. + + 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 SubTableContainerTable::Builder, + public RefCounted<GlyphTable::Builder> { + public: + // Note: Constructor scope altered to public for base class to instantiate. + Builder(Header* header, ReadableFontData* data); + virtual ~Builder(); + + virtual void SetLoca(const IntegerList& loca); + virtual void GenerateLocaList(IntegerList* locas); + + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + + // 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. The provided + // list and all contained objects belong to this builder. + // This call is only required if the entire set of glyphs in the glyph + // table builder are being replaced. If the glyph builder list provided from + // the GlyphTable.Builder::GlyphBuilders() is being used and modified + // then those changes will already be reflected in the glyph table builder. + 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. + explicit SimpleGlyphBuilder(WritableFontData* data); + explicit SimpleGlyphBuilder(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(); + virtual void Initialize(); + + 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 ParseData(bool fill_arrays); + int32_t FlagAsInt(int32_t index); + int32_t ContourEndPoint(int32_t contour); + + bool initialized_; + Lock initialization_lock_; + 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. + explicit CompositeGlyphBuilder(WritableFontData* data); + explicit CompositeGlyphBuilder(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(); + + protected: + virtual void Initialize(); + + private: + IntegerList contour_index_; + int32_t instruction_size_; + int32_t instructions_offset_; + bool initialized_; + Lock initialization_lock_; + }; + + 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 // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_ |