diff options
49 files changed, 1675 insertions, 886 deletions
diff --git a/sample/subsetter/subset_util.cc b/sample/subsetter/subset_util.cc index 26da65f..f35eb25 100644 --- a/sample/subsetter/subset_util.cc +++ b/sample/subsetter/subset_util.cc @@ -56,12 +56,11 @@ void SubsetUtil::Subset(const char *input_file_path, UNREFERENCED_PARAMETER(bytes_read); fclose(input_file); - ByteArrayPtr ba = new MemoryByteArray(&(input_buffer[0]), file_size); FontFactoryPtr factory; factory.Attach(FontFactory::GetInstance()); FontArray font_array; - factory->LoadFonts(ba, &font_array); + factory->LoadFonts(&input_buffer, &font_array); if (font_array.empty() || font_array[0] == NULL) return; diff --git a/sfntly/font.cc b/sfntly/font.cc index d66c9f6..e5e4401 100644 --- a/sfntly/font.cc +++ b/sfntly/font.cc @@ -23,6 +23,7 @@ #include <map> #include <string> #include <typeinfo> +#include <iterator> #include "sfntly/data/font_input_stream.h" #include "sfntly/font_factory.h" @@ -58,14 +59,14 @@ Table* Font::GetTable(int32_t tag) { return tables_[tag]; } -TableMap* Font::Tables() { +const TableMap* Font::GetTableMap() { return &tables_; } void Font::Serialize(OutputStream* os, IntegerList* table_ordering) { assert(table_ordering); IntegerList final_table_ordering; - TableOrdering(table_ordering, &final_table_ordering); + GenerateTableOrdering(table_ordering, &final_table_ordering); TableHeaderList table_records; BuildTableHeadersForSerialization(&final_table_ordering, &table_records); @@ -74,18 +75,11 @@ void Font::Serialize(OutputStream* os, IntegerList* table_ordering) { SerializeTables(&fos, &table_records); } -CALLER_ATTACH WritableFontData* Font::GetNewData(int32_t size) { - return factory_->GetNewData(size); -} - -Font::Font(FontFactory* factory, int32_t sfnt_version, ByteVector* digest, - TableMap* tables) - : factory_(factory), - sfnt_version_(sfnt_version) { +Font::Font(int32_t sfnt_version, ByteVector* digest) + : sfnt_version_(sfnt_version) { // non-trivial assignments that makes debugging hard if placed in // initialization list digest_ = *digest; - tables_ = *tables; } void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering, @@ -94,19 +88,22 @@ void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering, assert(table_ordering); IntegerList final_table_ordering; - TableOrdering(table_ordering, &final_table_ordering); + GenerateTableOrdering(table_ordering, &final_table_ordering); int32_t table_offset = Offset::kTableRecordBegin + num_tables() * Offset::kTableRecordSize; for (IntegerList::iterator tag = final_table_ordering.begin(), tag_end = final_table_ordering.end(); tag != tag_end; ++tag) { + if (tables_.find(*tag) == tables_.end()) { + continue; + } TablePtr table = tables_[*tag]; if (table != NULL) { TableHeaderPtr header = new Table::Header(*tag, table->CalculatedChecksum(), table_offset, - table->Length()); + table->header()->length()); table_headers->push_back(header); - table_offset += (table->Length() + 3) & ~3; + table_offset += (table->DataLength() + 3) & ~3; } } } @@ -121,9 +118,14 @@ void Font::SerializeHeader(FontOutputStream* fos, fos->WriteUShort(log2_of_max_power_of_2); fos->WriteUShort((table_headers->size() * 16) - search_range); - for (TableHeaderList::iterator record = table_headers->begin(), - record_end = table_headers->end(); - record != record_end; ++record) { + HeaderTagSortedSet sorted_headers; + std::copy(table_headers->begin(), + table_headers->end(), + std::inserter(sorted_headers, sorted_headers.end())); + + for (HeaderTagSortedSet::iterator record = sorted_headers.begin(), + record_end = sorted_headers.end(); + record != record_end; ++record) { fos->WriteULong((*record)->tag()); fos->WriteULong((int32_t)((*record)->checksum())); fos->WriteULong((*record)->offset()); @@ -133,30 +135,31 @@ void Font::SerializeHeader(FontOutputStream* fos, void Font::SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers) { - ByteVector SERIALIZATION_FILLER(3); - std::fill(SERIALIZATION_FILLER.begin(), SERIALIZATION_FILLER.end(), 0); + assert(fos); + assert(table_headers); for (TableHeaderList::iterator record = table_headers->begin(), end_of_headers = table_headers->end(); record != end_of_headers; ++record) { TablePtr target_table = GetTable((*record)->tag()); if (target_table == NULL) { -#if defined (SFNTLY_NO_EXCEPTION) - return; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("Table out of sync with font header."); #endif + return; } int32_t table_size = target_table->Serialize(fos); if (table_size != (*record)->length()) { assert(false); } int32_t filler_size = ((table_size + 3) & ~3) - table_size; - fos->Write(&SERIALIZATION_FILLER, 0, filler_size); + for (int32_t i = 0; i < filler_size; ++i) { + fos->Write(static_cast<byte_t>(0)); + } } } -void Font::TableOrdering(IntegerList* default_table_ordering, - IntegerList* table_ordering) { +void Font::GenerateTableOrdering(IntegerList* default_table_ordering, + IntegerList* table_ordering) { assert(default_table_ordering); assert(table_ordering); table_ordering->clear(); @@ -207,17 +210,19 @@ void Font::DefaultTableOrdering(IntegerList* default_table_ordering) { ******************************************************************************/ Font::Builder::~Builder() {} -CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( - FontFactory* factory, InputStream* is) { +CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory, + InputStream* is) { FontBuilderPtr builder = new Builder(factory); builder->LoadFont(is); return builder.Detach(); } CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder( - FontFactory* factory, ByteArray* ba, int32_t offset_to_offset_table) { + FontFactory* factory, + WritableFontData* wfd, + int32_t offset_to_offset_table) { FontBuilderPtr builder = new Builder(factory); - builder->LoadFont(ba, offset_to_offset_table); + builder->LoadFont(wfd, offset_to_offset_table); return builder.Detach(); } @@ -233,7 +238,7 @@ bool Font::Builder::ReadyToBuild() { return true; } - // TODO(stuartg): font level checks - required tables etc. + // TODO(stuartg): font level checks - required tables etc? for (TableBuilderMap::iterator table_builder = table_builders_.begin(), table_builder_end = table_builders_.end(); table_builder != table_builder_end; @@ -245,31 +250,25 @@ bool Font::Builder::ReadyToBuild() { } CALLER_ATTACH Font* Font::Builder::Build() { - TableMap tables; + FontPtr font = new Font(sfnt_version_, &digest_); + if (!table_builders_.empty()) { - BuildTablesFromBuilders(&table_builders_, &tables); + // Note: Different from Java. Directly use font->tables_ here to avoid + // STL container copying. + BuildTablesFromBuilders(font, &table_builders_, &font->tables_); } - FontPtr font = new Font(factory_, sfnt_version_, &digest_, &tables); + table_builders_.clear(); data_blocks_.clear(); return font.Detach(); } -CALLER_ATTACH WritableFontData* Font::Builder::GetNewData(int32_t capacity) { - return factory_->GetNewData(capacity); -} - -CALLER_ATTACH WritableFontData* Font::Builder::GetNewGrowableData( - ReadableFontData* src_data) { - return factory_->GetNewGrowableData(src_data); -} - void Font::Builder::SetDigest(ByteVector* digest) { digest_.clear(); digest_ = *digest; } -void Font::Builder::CleanTableBuilders() { +void Font::Builder::ClearTableBuilders() { table_builders_.clear(); } @@ -286,31 +285,32 @@ Table::Builder* Font::Builder::GetTableBuilder(int32_t tag) { Table::Builder* Font::Builder::NewTableBuilder(int32_t tag) { TableHeaderPtr header = new Table::Header(tag); TableBuilderPtr builder; - builder.Attach(Table::Builder::GetBuilder(this, header, NULL)); + builder.Attach(Table::Builder::GetBuilder(header, NULL)); table_builders_.insert(TableBuilderEntry(header->tag(), builder)); return builder; } Table::Builder* Font::Builder::NewTableBuilder(int32_t tag, ReadableFontData* src_data) { + assert(src_data); WritableFontDataPtr data; - data.Attach(GetNewGrowableData(src_data)); - TableHeaderPtr header = new Table::Header(tag); + data.Attach(WritableFontData::CreateWritableFontData(src_data->Length())); +#if !defined (SFNTLY_NO_EXCEPTION) + try { +#endif + src_data->CopyTo(data); +#if !defined (SFNTLY_NO_EXCEPTION) + } catch (IOException& e) { + return NULL; + } +#endif + TableHeaderPtr header = new Table::Header(tag, data->Length()); TableBuilderPtr builder; - builder.Attach(Table::Builder::GetBuilder(this, header, data)); + builder.Attach(Table::Builder::GetBuilder(header, data)); table_builders_.insert(TableBuilderEntry(tag, builder)); return builder; } -void Font::Builder::TableBuilderTags(IntegerSet* key_set) { - assert(key_set); - key_set->clear(); - for (TableBuilderMap::iterator i = table_builders_.begin(), - e = table_builders_.end(); i != e; ++i) { - key_set->insert(i->first); - } -} - void Font::Builder::RemoveTableBuilder(int32_t tag) { TableBuilderMap::iterator target = table_builders_.find(tag); if (target != table_builders_.end()) { @@ -326,21 +326,20 @@ void Font::Builder::LoadFont(InputStream* is) { // Note: we do not throw exception here for is. This is more of an assertion. assert(is); FontInputStream font_is(is); - TableHeaderSortedSet records; + HeaderOffsetSortedSet records; ReadHeader(&font_is, &records); LoadTableData(&records, &font_is, &data_blocks_); BuildAllTableBuilders(&data_blocks_, &table_builders_); font_is.Close(); } -void Font::Builder::LoadFont(ByteArray* ba, +void Font::Builder::LoadFont(WritableFontData* wfd, int32_t offset_to_offset_table) { // Note: we do not throw exception here for is. This is more of an assertion. - assert(ba); - WritableFontDataPtr fd = new WritableFontData(ba); - TableHeaderSortedSet records; - ReadHeader(fd, offset_to_offset_table, &records); - LoadTableData(&records, fd, &data_blocks_); + assert(wfd); + HeaderOffsetSortedSet records; + ReadHeader(wfd, offset_to_offset_table, &records); + LoadTableData(&records, wfd, &data_blocks_); BuildAllTableBuilders(&data_blocks_, &table_builders_); } @@ -361,14 +360,16 @@ void Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data, InterRelateBuilders(&table_builders_); } -CALLER_ATTACH Table::Builder* - Font::Builder::GetTableBuilder(Table::Header* header, - WritableFontData* data) { - return Table::Builder::GetBuilder(this, header, data); +CALLER_ATTACH +Table::Builder* Font::Builder::GetTableBuilder(Table::Header* header, + WritableFontData* data) { + return Table::Builder::GetBuilder(header, data); } -void Font::Builder::BuildTablesFromBuilders(TableBuilderMap* builder_map, +void Font::Builder::BuildTablesFromBuilders(Font* font, + TableBuilderMap* builder_map, TableMap* table_map) { + UNREFERENCED_PARAMETER(font); InterRelateBuilders(builder_map); // Now build all the tables. @@ -384,7 +385,7 @@ void Font::Builder::BuildTablesFromBuilders(TableBuilderMap* builder_map, #if !defined (SFNTLY_NO_EXCEPTION) } catch(IOException& e) { std::string builder_string = "Unable to build table - "; - char *table_name = TagToString(builder->first); + char* table_name = TagToString(builder->first); builder_string += table_name; delete[] table_name; throw RuntimeException(builder_string.c_str()); @@ -392,20 +393,19 @@ void Font::Builder::BuildTablesFromBuilders(TableBuilderMap* builder_map, #endif } if (table == NULL) { - std::string builder_string = "Unable to build table - "; - char *table_name = TagToString(builder->first); - builder_string += table_name; - delete[] table_name; -#if defined (SFNTLY_NO_EXCEPTION) #if defined (SFNTLY_DEBUG) fprintf(stderr, "Aborting table construction: %s\n", builder_string.c_str()); #endif table_map->clear(); - return; -#else +#if !defined (SFNTLY_NO_EXCEPTION) + std::string builder_string = "Unable to build table - "; + char* table_name = TagToString(builder->first); + builder_string += table_name; + delete[] table_name; throw RuntimeException(builder_string.c_str()); #endif + return; } table_map->insert(TableMapEntry(table->header()->tag(), table)); } @@ -474,14 +474,14 @@ void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); } if (header_table_builder != NULL) { - loca_table_builder->SetFormatVersion( + loca_table_builder->set_format_version( header_table_builder->IndexToLocFormat()); } } } void Font::Builder::ReadHeader(FontInputStream* is, - TableHeaderSortedSet* records) { + HeaderOffsetSortedSet* records) { assert(records); sfnt_version_ = is->ReadFixed(); num_tables_ = is->ReadUShort(); @@ -503,7 +503,7 @@ void Font::Builder::ReadHeader(FontInputStream* is, void Font::Builder::ReadHeader(ReadableFontData* fd, int32_t offset, - TableHeaderSortedSet* records) { + HeaderOffsetSortedSet* records) { assert(records); sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion); num_tables_ = fd->ReadUShort(offset + Offset::kNumTables); @@ -524,13 +524,14 @@ void Font::Builder::ReadHeader(ReadableFontData* fd, } } -void Font::Builder::LoadTableData(TableHeaderSortedSet* headers, +void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, FontInputStream* is, DataBlockMap* table_data) { assert(table_data); - for (TableHeaderSortedSet::iterator - table_header = headers->begin(), table_end = headers->end(); - table_header != table_end; ++table_header) { + for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), + table_end = headers->end(); + table_header != table_end; + ++table_header) { is->Skip((*table_header)->offset() - is->position()); FontInputStream table_is(is, (*table_header)->length()); WritableFontDataPtr data; @@ -541,12 +542,13 @@ void Font::Builder::LoadTableData(TableHeaderSortedSet* headers, } } -void Font::Builder::LoadTableData(TableHeaderSortedSet* headers, +void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, WritableFontData* fd, DataBlockMap* table_data) { - for (TableHeaderSortedSet::iterator - table_header = headers->begin(), table_end = headers->end(); - table_header != table_end; ++table_header) { + for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), + table_end = headers->end(); + table_header != table_end; + ++table_header) { FontDataPtr sliced_data; sliced_data.Attach( fd->Slice((*table_header)->offset(), (*table_header)->length())); diff --git a/sfntly/font.h b/sfntly/font.h index 2badece..1a714a6 100644 --- a/sfntly/font.h +++ b/sfntly/font.h @@ -22,7 +22,6 @@ #include "sfntly/port/refcount.h" #include "sfntly/port/type.h" #include "sfntly/port/endian.h" -#include "sfntly/font_data_table_builder_container.h" #include "sfntly/data/font_input_stream.h" #include "sfntly/data/font_output_stream.h" #include "sfntly/data/writable_font_data.h" @@ -121,10 +120,16 @@ struct MacintoshEncodingId { extern const int32_t SFNTVERSION_1; class FontFactory; + +// An sfnt container font object. This object is immutable and thread safe. To +// construct one use an instance of Font::Builder. class Font : public RefCounted<Font> { public: - class Builder : public FontDataTableBuilderContainer, - public RefCounted<Builder> { + // A builder for a font object. The builder allows the for the creation of + // immutable Font objects. The builder is a one use non-thread safe object and + // once the Font object has been created it is no longer usable. To create a + // further Font object new builder will be required. + class Builder : public RefCounted<Builder> { public: virtual ~Builder(); @@ -132,18 +137,31 @@ class Font : public RefCounted<Font> { GetOTFBuilder(FontFactory* factory, InputStream* is); static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory, - ByteArray* ba, + WritableFontData* ba, int32_t offset_to_offset_table); static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory); - virtual bool ReadyToBuild(); - virtual CALLER_ATTACH Font* Build(); - virtual CALLER_ATTACH WritableFontData* GetNewData(int32_t capacity); - virtual CALLER_ATTACH WritableFontData* - GetNewGrowableData(ReadableFontData* data); - virtual void SetDigest(ByteVector* digest); - virtual void CleanTableBuilders(); - virtual bool HasTableBuilder(int32_t tag); - virtual Table::Builder* GetTableBuilder(int32_t tag); + + // Get the font factory that created this font builder. + FontFactory* GetFontFactory() { return factory_; } + + // Is the font ready to build? + bool ReadyToBuild(); + + // Build the Font. After this call this builder will no longer be usable. + CALLER_ATTACH Font* Build(); + + // Set a unique fingerprint for the font object. + void SetDigest(ByteVector* digest); + + // Clear all table builders. + void ClearTableBuilders(); + + // Does this font builder have the specified table builder. + bool HasTableBuilder(int32_t tag); + + // Get the table builder for the given tag. If there is no builder for that + // tag then return a null. + Table::Builder* GetTableBuilder(int32_t tag); // Creates a new table builder for the table type given by the table id tag. // This new table has been added to the font and will replace any existing @@ -151,12 +169,23 @@ class Font : public RefCounted<Font> { // @return new empty table of the type specified by tag; if tag is not known // then a generic OpenTypeTable is returned virtual Table::Builder* NewTableBuilder(int32_t tag); + + // Creates a new table builder for the table type given by the table id tag. + // It makes a copy of the data provided and uses that copy for the table. + // This new table has been added to the font and will replace any existing + // builder for that table. virtual Table::Builder* NewTableBuilder(int32_t tag, ReadableFontData* src_data); + + // Get a map of the table builders in this font builder accessed by table + // tag. virtual TableBuilderMap* table_builders() { return &table_builders_; } - virtual void TableBuilderTags(IntegerSet* key_set); + + // Remove the specified table builder from the font builder. // Note: different from Java: we don't return object in removeTableBuilder virtual void RemoveTableBuilder(int32_t tag); + + // Get the number of table builders in the font builder. virtual int32_t number_of_table_builders() { return (int32_t)table_builders_.size(); } @@ -164,23 +193,30 @@ class Font : public RefCounted<Font> { private: explicit Builder(FontFactory* factory); virtual void LoadFont(InputStream* is); - virtual void LoadFont(ByteArray* buffer, int32_t offset_to_offset_table); + virtual void LoadFont(WritableFontData* wfd, + int32_t offset_to_offset_table); int32_t SfntWrapperSize(); void BuildAllTableBuilders(DataBlockMap* table_data, TableBuilderMap* builder_map); CALLER_ATTACH Table::Builder* GetTableBuilder(Table::Header* header, WritableFontData* data); - void BuildTablesFromBuilders(TableBuilderMap* builder_map, + void BuildTablesFromBuilders(Font* font, + TableBuilderMap* builder_map, TableMap* tables); static void InterRelateBuilders(TableBuilderMap* builder_map); - void ReadHeader(FontInputStream* is, TableHeaderSortedSet* records); + + void ReadHeader(FontInputStream* is, + HeaderOffsetSortedSet* records); + void ReadHeader(ReadableFontData* fd, int32_t offset, - TableHeaderSortedSet* records); - void LoadTableData(TableHeaderSortedSet* headers, + HeaderOffsetSortedSet* records); + + void LoadTableData(HeaderOffsetSortedSet* headers, FontInputStream* is, DataBlockMap* table_data); - void LoadTableData(TableHeaderSortedSet* headers, + + void LoadTableData(HeaderOffsetSortedSet* headers, WritableFontData* fd, DataBlockMap* table_data); @@ -198,7 +234,7 @@ class Font : public RefCounted<Font> { virtual ~Font(); // Gets the sfnt version set in the sfnt wrapper of the font. - int32_t version() { return sfnt_version_; } + int32_t sfnt_version() { return sfnt_version_; } // Gets a copy of the fonts digest that was created when the font was read. If // no digest was set at creation time then the return result will be null. @@ -223,24 +259,16 @@ class Font : public RefCounted<Font> { // Get a map of the tables in this font accessed by table tag. // @return an unmodifiable view of the tables in this font - TableMap* Tables(); + // Note: renamed tableMap() to GetTableMap() + const TableMap* GetTableMap(); + + // UNIMPLEMENTED: toString() // Serialize the font to the output stream. // @param os the destination for the font serialization // @param tableOrdering the table ordering to apply void Serialize(OutputStream* os, IntegerList* table_ordering); - // Get a new data object. The size is a request for a data object and the - // returned data object will support at least that amount. A value greater - // than zero for the size is a request for a fixed size data object. A - // negative or zero value for the size is a request for a variable sized data - // object with the absolute value of the size being an estimate of the space - // required. - // @param size greater than zero is a request for a fixed size data object of - // the given size; less than or equal to zero is a request for a - // variable size data object with the absolute size as an estimate - CALLER_ATTACH WritableFontData* GetNewData(int32_t size); - private: // Offsets to specific elements in the underlying data. These offsets are // relative to the start of the table or the start of sub-blocks within the @@ -269,18 +297,48 @@ class Font : public RefCounted<Font> { // static const int32_t CFF_TABLE_ORDERING[]; // static const int32_t TRUE_TYPE_TABLE_ORDERING[]; - Font(FontFactory* factory, int32_t sfnt_version, ByteVector* digest, - TableMap* tables); - + // Constructor. + // @param sfntVersion the sfnt version + // @param digest the computed digest for the font; null if digest was not + // computed + // Note: Current C++ port does not support SHA digest validation. + Font(int32_t sfnt_version, ByteVector* digest); + + // Build the table headers to be used for serialization. These headers will be + // filled out with the data required for serialization. The headers will be + // sorted in the order specified and only those specified will have headers + // generated. + // @param tableOrdering the tables to generate headers for and the order to + // sort them + // @return a list of table headers ready for serialization void BuildTableHeadersForSerialization(IntegerList* table_ordering, TableHeaderList* table_headers); + + // Searialize the headers. + // @param fos the destination stream for the headers + // @param tableHeaders the headers to serialize + // @throws IOException void SerializeHeader(FontOutputStream* fos, TableHeaderList* table_headers); + + // Serialize the tables. + // @param fos the destination stream for the headers + // @param tableHeaders the headers for the tables to serialize + // @throws IOException void SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers); - void TableOrdering(IntegerList* default_table_ordering, - IntegerList* table_ordering); + + // Generate the full table ordering to used for serialization. The full + // ordering uses the partial ordering as a seed and then adds all remaining + // tables in the font in an undefined order. + // @param defaultTableOrdering the partial ordering to be used as a seed for + // the full ordering + // @param (out) table_ordering the full ordering for serialization + void GenerateTableOrdering(IntegerList* default_table_ordering, + IntegerList* table_ordering); + + // Get the default table ordering based on the type of the font. + // @param (out) default_table_ordering the default table ordering void DefaultTableOrdering(IntegerList* default_table_ordering); - FontFactory* factory_; // dumb pointer, avoid circular ref-counting int32_t sfnt_version_; ByteVector digest_; int64_t checksum_; diff --git a/sfntly/font_data_table_builder_container.h b/sfntly/font_data_table_builder_container.h deleted file mode 100644 index 2818464..0000000 --- a/sfntly/font_data_table_builder_container.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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_FONT_DATA_TABLE_BUILDER_CONTAINER_H_ -#define SFNTLY_CPP_SRC_SFNTLY_FONT_DATA_TABLE_BUILDER_CONTAINER_H_ - -#include "sfntly/data/writable_font_data.h" - -namespace sfntly { - -class FontDataTableBuilderContainer { - public: - virtual WritableFontData* GetNewData(int32_t size) = 0; - // Make gcc -Wnon-virtual-dtor happy. - virtual ~FontDataTableBuilderContainer() {} -}; -typedef Ptr<FontDataTableBuilderContainer> FontDataTableBuilderContainerPtr; - -} // namespace sfntly - -#endif // SFNTLY_CPP_SRC_SFNTLY_FONT_DATA_TABLE_BUILDER_CONTAINER_H_ diff --git a/sfntly/font_factory.cc b/sfntly/font_factory.cc index a306bcd..c162a77 100644 --- a/sfntly/font_factory.cc +++ b/sfntly/font_factory.cc @@ -19,8 +19,6 @@ #include <string.h> #include "sfntly/tag.h" -#include "sfntly/data/memory_byte_array.h" -#include "sfntly/data/growable_memory_byte_array.h" namespace sfntly { @@ -54,13 +52,15 @@ void FontFactory::LoadFonts(InputStream* is, FontArray* output) { } } -void FontFactory::LoadFonts(ByteArray* ba, FontArray* output) { - if (IsCollection(ba)) { - LoadCollection(ba, output); +void FontFactory::LoadFonts(ByteVector* b, FontArray* output) { + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(b)); + if (IsCollection(wfd)) { + LoadCollection(wfd, output); return; } FontPtr font; - font.Attach(LoadSingleOTF(ba)); + font.Attach(LoadSingleOTF(wfd)); if (font) { output->push_back(font); } @@ -80,59 +80,21 @@ void FontFactory::LoadFontsForBuilding(InputStream* is, } } -void FontFactory::LoadFontsForBuilding(ByteArray* ba, +void FontFactory::LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output) { - if (IsCollection(ba)) { - LoadCollectionForBuilding(ba, output); + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(b)); + if (IsCollection(wfd)) { + LoadCollectionForBuilding(wfd, output); return; } FontBuilderPtr builder; - builder.Attach(LoadSingleOTFForBuilding(ba, 0)); + builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); if (builder) { output->push_back(builder); } } -CALLER_ATTACH WritableFontData* FontFactory::GetNewData(int32_t capacity) { - // UNIMPLMENTED: if (capacity > 0) { this.GetNewFixedData(capacity); } - // Seems a no-op. - return GetNewGrowableData(capacity); -} - -CALLER_ATTACH WritableFontData* FontFactory::GetNewFixedData(int32_t capacity) { - ByteArrayPtr buffer; - buffer.Attach(GetNewArray(capacity)); - WritableFontDataPtr new_fixed_data = new WritableFontData(buffer); - return new_fixed_data.Detach(); -} - -CALLER_ATTACH WritableFontData* FontFactory::GetNewGrowableData( - int32_t capacity) { - ByteArrayPtr buffer; - buffer.Attach(GetNewGrowableArray(capacity)); - WritableFontDataPtr new_growable_data = new WritableFontData(buffer); - return new_growable_data.Detach(); -} - -CALLER_ATTACH WritableFontData* FontFactory::GetNewGrowableData( - ReadableFontData* src_data) { - WritableFontDataPtr data; - data.Attach(GetNewGrowableData(src_data->Length())); - src_data->CopyTo(data); - return data.Detach(); -} - -CALLER_ATTACH ByteArray* FontFactory::GetNewArray(int32_t length) { - ByteArrayPtr new_fixed_array = new MemoryByteArray(length); - return new_fixed_array.Detach(); -} - -CALLER_ATTACH ByteArray* FontFactory::GetNewGrowableArray(int32_t length) { - UNREFERENCED_PARAMETER(length); - ByteArrayPtr new_growable_array = new GrowableMemoryByteArray(); - return new_growable_array.Detach(); -} - void FontFactory::SerializeFont(Font* font, OutputStream* os) { font->Serialize(os, &table_ordering_); } @@ -152,9 +114,9 @@ CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) { return builder->Build(); } -CALLER_ATTACH Font* FontFactory::LoadSingleOTF(ByteArray* ba) { +CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) { FontBuilderPtr builder; - builder.Attach(LoadSingleOTFForBuilding(ba, 0)); + builder.Attach(LoadSingleOTFForBuilding(wfd, 0)); return builder->Build(); } @@ -170,21 +132,21 @@ void FontFactory::LoadCollection(InputStream* is, FontArray* output) { } } -void FontFactory::LoadCollection(ByteArray* ba, FontArray* output) { +void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) { FontBuilderArray builders; - LoadCollectionForBuilding(ba, &builders); - output->reserve(ba->Size()); - for (FontBuilderArray::iterator - builder = builders.begin(), builders_end = builders.end(); - builder != builders_end; ++builder) { + LoadCollectionForBuilding(wfd, &builders); + output->reserve(builders.size()); + for (FontBuilderArray::iterator builder = builders.begin(), + builders_end = builders.end(); + builder != builders_end; ++builder) { FontPtr font; font.Attach((*builder)->Build()); output->push_back(font); } } -CALLER_ATTACH Font::Builder* - FontFactory::LoadSingleOTFForBuilding(InputStream* is) { +CALLER_ATTACH +Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) { // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is); // UNIMPLEMENTED: setDigest @@ -192,38 +154,41 @@ CALLER_ATTACH Font::Builder* } CALLER_ATTACH Font::Builder* - FontFactory::LoadSingleOTFForBuilding(ByteArray* ba, + FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd, int32_t offset_to_offset_table) { // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream Font::Builder* builder = - Font::Builder::GetOTFBuilder(this, ba, offset_to_offset_table); + Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table); // UNIMPLEMENTED: setDigest return builder; } void FontFactory::LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders) { - ByteArrayPtr ba = new GrowableMemoryByteArray(); - ba->CopyFrom(is); - LoadCollectionForBuilding(ba, builders); + assert(is); + assert(builders); + WritableFontDataPtr wfd; + wfd.Attach(WritableFontData::CreateWritableFontData(is->Available())); + wfd->CopyFrom(is); + LoadCollectionForBuilding(wfd, builders); } -void FontFactory::LoadCollectionForBuilding(ByteArray* ba, +void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd, FontBuilderArray* builders) { - ReadableFontDataPtr rfd = new ReadableFontData(ba); - int32_t ttc_tag = rfd->ReadULongAsInt(Offset::kTTCTag); + int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag); UNREFERENCED_PARAMETER(ttc_tag); - int32_t version = rfd->ReadFixed(Offset::kVersion); + int32_t version = wfd->ReadFixed(Offset::kVersion); UNREFERENCED_PARAMETER(version); - int32_t num_fonts = rfd->ReadULongAsInt(Offset::kNumFonts); + int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts); builders->reserve(num_fonts); int32_t offset_table_offset = Offset::kOffsetTable; - for (int32_t font_number = 0; font_number < num_fonts; - font_number++, offset_table_offset += DataSize::kULONG) { - int32_t offset = rfd->ReadULongAsInt(offset_table_offset); + for (int32_t font_number = 0; + font_number < num_fonts; + font_number++, offset_table_offset += DataSize::kULONG) { + int32_t offset = wfd->ReadULongAsInt(offset_table_offset); FontBuilderPtr builder; - builder.Attach(LoadSingleOTFForBuilding(ba, offset)); + builder.Attach(LoadSingleOTFForBuilding(wfd, offset)); builders->push_back(builder); } } @@ -235,9 +200,11 @@ bool FontFactory::IsCollection(PushbackInputStream* pbis) { return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]); } -bool FontFactory::IsCollection(ByteArray* ba) { +bool FontFactory::IsCollection(ReadableFontData* rfd) { + ByteVector tag(4); + rfd->ReadBytes(0, &(tag[0]), 0, tag.size()); return Tag::ttcf == - GenerateTag(ba->Get(0), ba->Get(1), ba->Get(2), ba->Get(3)); + GenerateTag(tag[0], tag[1], tag[2], tag[3]); } FontFactory::FontFactory() diff --git a/sfntly/font_factory.h b/sfntly/font_factory.h index b706b92..63deff4 100644 --- a/sfntly/font_factory.h +++ b/sfntly/font_factory.h @@ -56,7 +56,7 @@ class FontFactory : public RefCounted<FontFactory> { // than one font and in this case multiple font objects will be returned. If // the data in the stream cannot be parsed or is invalid an array of size zero // will be returned. - void LoadFonts(ByteArray* ba, FontArray* output); + void LoadFonts(ByteVector* b, FontArray* output); // Load the font(s) from the input stream into font builders. The current // settings on the factory are used during the loading process. One or more @@ -72,15 +72,7 @@ class FontFactory : public RefCounted<FontFactory> { // font container formats may have more than one font and in this case // multiple font builder objects will be returned. If the data in the stream // cannot be parsed or is invalid an array of size zero will be returned. - void LoadFontsForBuilding(ByteArray* ba, FontBuilderArray* output); - - CALLER_ATTACH WritableFontData* GetNewData(int32_t capacity); - CALLER_ATTACH WritableFontData* GetNewFixedData(int32_t capacity); - CALLER_ATTACH WritableFontData* GetNewGrowableData(int32_t capacity); - CALLER_ATTACH WritableFontData* - GetNewGrowableData(ReadableFontData* src_data); - CALLER_ATTACH ByteArray* GetNewArray(int32_t length); - CALLER_ATTACH ByteArray* GetNewGrowableArray(int32_t length); + void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output); // Font serialization // Serialize the font to the output stream. @@ -121,20 +113,22 @@ class FontFactory : public RefCounted<FontFactory> { FontFactory(); CALLER_ATTACH Font* LoadSingleOTF(InputStream* is); - CALLER_ATTACH Font* LoadSingleOTF(ByteArray* ba); + CALLER_ATTACH Font* LoadSingleOTF(WritableFontData* wfd); void LoadCollection(InputStream* is, FontArray* output); - void LoadCollection(ByteArray* ba, FontArray* output); + void LoadCollection(WritableFontData* wfd, FontArray* output); CALLER_ATTACH Font::Builder* LoadSingleOTFForBuilding(InputStream* is); CALLER_ATTACH Font::Builder* - LoadSingleOTFForBuilding(ByteArray* ba, int32_t offset_to_offset_table); + LoadSingleOTFForBuilding(WritableFontData* wfd, + int32_t offset_to_offset_table); void LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders); - void LoadCollectionForBuilding(ByteArray* ba, FontBuilderArray* builders); + void LoadCollectionForBuilding(WritableFontData* ba, + FontBuilderArray* builders); static bool IsCollection(PushbackInputStream* pbis); - static bool IsCollection(ByteArray* ba); + static bool IsCollection(ReadableFontData* wfd); bool fingerprint_; IntegerList table_ordering_; diff --git a/sfntly/port/config.h b/sfntly/port/config.h index 01c4685..0fcdffe 100644 --- a/sfntly/port/config.h +++ b/sfntly/port/config.h @@ -19,9 +19,9 @@ #if !defined(SFNTLY_BIG_ENDIAN) && !defined(SFNTLY_LITTLE_ENDIAN) #if defined (__ppc__) || defined (__ppc64__) - #define SFNTLY_CPP_BIG_ENDIAN + #define SFNTLY_BIG_ENDIAN #else - #define SFNTLY_CPP_LITTLE_ENDIAN + #define SFNTLY_LITTLE_ENDIAN #endif #endif diff --git a/sfntly/port/file_input_stream.cc b/sfntly/port/file_input_stream.cc index 661b6fd..5bcb434 100644 --- a/sfntly/port/file_input_stream.cc +++ b/sfntly/port/file_input_stream.cc @@ -57,18 +57,16 @@ bool FileInputStream::MarkSupported() { int32_t FileInputStream::Read() { if (!file_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("no opened file"); #endif + return 0; } if (feof(file_)) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("eof reached"); #endif + return 0; } byte_t value; size_t length = fread(&value, 1, 1, file_); @@ -77,24 +75,22 @@ int32_t FileInputStream::Read() { } int32_t FileInputStream::Read(ByteVector* b) { - return Read(b, 0, b->capacity()); + return Read(b, 0, b->size()); } int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) { assert(b); if (!file_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("no opened file"); #endif + return 0; } if (feof(file_)) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("eof reached"); #endif + return 0; } size_t read_count = std::min<size_t>(length_ - position_, length); if (b->size() < (size_t)(offset + read_count)) { @@ -111,11 +107,10 @@ void FileInputStream::Reset() { int64_t FileInputStream::Skip(int64_t n) { if (!file_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("no opened file"); #endif + return 0; } int64_t skip_count = 0; if (n < 0) { // move backwards @@ -131,18 +126,17 @@ int64_t FileInputStream::Skip(int64_t n) { } void FileInputStream::Unread(ByteVector* b) { - Unread(b, 0, b->capacity()); + Unread(b, 0, b->size()); } void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) { assert(b); assert(b->size() >= size_t(offset + length)); if (!file_) { -#if defined (SFNTLY_NO_EXCEPTION) - return; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IOException("no opened file"); #endif + return; } size_t unread_count = std::min<size_t>(position_, length); fseek(file_, position_ - unread_count, SEEK_SET); diff --git a/sfntly/port/memory_input_stream.cc b/sfntly/port/memory_input_stream.cc new file mode 100755 index 0000000..56ee81e --- /dev/null +++ b/sfntly/port/memory_input_stream.cc @@ -0,0 +1,147 @@ +/* + * 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. + */ + +#if defined (WIN32) +#include <windows.h> +#endif + +#include <string.h> + +#include "sfntly/port/memory_input_stream.h" +#include "sfntly/port/exception_type.h" + +namespace sfntly { + +MemoryInputStream::MemoryInputStream() + : buffer_(NULL), + position_(0), + length_(0) { +} + +MemoryInputStream::~MemoryInputStream() { + Close(); +} + +int32_t MemoryInputStream::Available() { + return length_ - position_; +} + +void MemoryInputStream::Close() { +} + +void MemoryInputStream::Mark(int32_t readlimit) { + // NOP + UNREFERENCED_PARAMETER(readlimit); +} + +bool MemoryInputStream::MarkSupported() { + return false; +} + +int32_t MemoryInputStream::Read() { + if (!buffer_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("no memory attached"); +#endif + return 0; + } + if (position_ >= length_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("eof reached"); +#endif + return 0; + } + byte_t value = buffer_[position_++]; + return value; +} + +int32_t MemoryInputStream::Read(ByteVector* b) { + return Read(b, 0, b->size()); +} + +int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) { + assert(b); + if (!buffer_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("no memory attached"); +#endif + return 0; + } + if (position_ >= length_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("eof reached"); +#endif + return 0; + } + size_t read_count = std::min<size_t>(length_ - position_, length); + if (b->size() < (size_t)(offset + read_count)) { + b->resize((size_t)(offset + read_count)); + } + memcpy(&((*b)[offset]), buffer_ + position_, read_count); + position_ += read_count; + return read_count; +} + +void MemoryInputStream::Reset() { + // NOP +} + +int64_t MemoryInputStream::Skip(int64_t n) { + if (!buffer_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("no memory attached"); +#endif + return 0; + } + int64_t skip_count = 0; + if (n < 0) { // move backwards + skip_count = std::max<int64_t>(0 - (int64_t)position_, n); + position_ -= (size_t)(0 - skip_count); + } else { + skip_count = std::min<size_t>(length_ - position_, (size_t)n); + position_ += (size_t)skip_count; + } + return skip_count; +} + +void MemoryInputStream::Unread(ByteVector* b) { + Unread(b, 0, b->size()); +} + +void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) { + assert(b); + assert(b->size() >= size_t(offset + length)); + if (!buffer_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IOException("no memory attached"); +#endif + return; + } + size_t unread_count = std::min<size_t>(position_, length); + position_ -= unread_count; + Read(b, offset, length); + position_ -= unread_count; +} + +bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) { + assert(buffer); + assert(length); + buffer_ = buffer; + length_ = length; + return true; +} + +} // namespace sfntly diff --git a/sfntly/port/memory_input_stream.h b/sfntly/port/memory_input_stream.h new file mode 100755 index 0000000..bc861c3 --- /dev/null +++ b/sfntly/port/memory_input_stream.h @@ -0,0 +1,57 @@ +/* + * 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_PORT_MEMORY_INPUT_STREAM_H_ +#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_ + +#include <stdio.h> + +#include "sfntly/port/input_stream.h" + +namespace sfntly { + +class MemoryInputStream : public PushbackInputStream { + public: + MemoryInputStream(); + virtual ~MemoryInputStream(); + + // InputStream methods + virtual int32_t Available(); + virtual void Close(); + virtual void Mark(int32_t readlimit); + virtual bool MarkSupported(); + virtual int32_t Read(); + virtual int32_t Read(ByteVector* b); + virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length); + virtual void Reset(); + virtual int64_t Skip(int64_t n); + + // PushbackInputStream methods + virtual void Unread(ByteVector* b); + virtual void Unread(ByteVector* b, int32_t offset, int32_t length); + + // Own methods + virtual bool Attach(const byte_t* buffer, size_t length); + + private: + const byte_t* buffer_; + size_t position_; + size_t length_; +}; + +} // namespace sfntly + +#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_ diff --git a/sfntly/table/core/cmap_table.cc b/sfntly/table/core/cmap_table.cc index 7217265..dd43996 100644 --- a/sfntly/table/core/cmap_table.cc +++ b/sfntly/table/core/cmap_table.cc @@ -60,7 +60,7 @@ int32_t CMapTable::Offset(int32_t index) { } CMapTable::CMapTable(Header* header, ReadableFontData* data) - : Table(header, data) { + : SubTableContainerTable(header, data) { } int32_t CMapTable::OffsetForEncodingRecord(int32_t index) { @@ -126,20 +126,18 @@ CMapTable::CMap::Builder::~Builder() { } CALLER_ATTACH CMapTable::CMap::Builder* - CMapTable::CMap::Builder::GetBuilder( - FontDataTableBuilderContainer* container, - ReadableFontData* data, - int32_t offset, - const CMapId& cmap_id) { + CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, + int32_t offset, + const CMapId& cmap_id) { // NOT IMPLEMENTED: Java enum value validation int32_t format = data->ReadUShort(offset); CMapBuilderPtr builder; switch (format) { case CMapFormat::kFormat0: - builder = new CMapFormat0::Builder(container, data, offset, cmap_id); + builder = new CMapFormat0::Builder(data, offset, cmap_id); break; case CMapFormat::kFormat2: - builder = new CMapFormat0::Builder(container, data, offset, cmap_id); + builder = new CMapFormat0::Builder(data, offset, cmap_id); break; default: break; @@ -147,18 +145,18 @@ CALLER_ATTACH CMapTable::CMap::Builder* return builder.Detach(); } -CMapTable::CMap::Builder::Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data, int32_t format, +CMapTable::CMap::Builder::Builder(ReadableFontData* data, + int32_t format, const CMapId& cmap_id) - : SubTable::Builder(container, data), + : SubTable::Builder(data), format_(format), cmap_id_(cmap_id) { } -CMapTable::CMap::Builder::Builder(FontDataTableBuilderContainer* container, - WritableFontData* data, int32_t format, +CMapTable::CMap::Builder::Builder(WritableFontData* data, + int32_t format, const CMapId& cmap_id) - : SubTable::Builder(container, data), + : SubTable::Builder(data), format_(format), cmap_id_(cmap_id) { } @@ -204,13 +202,10 @@ CMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data, /****************************************************************************** * CMapTable::CMapFormat0::Builder ******************************************************************************/ -CMapTable::CMapFormat0::Builder::Builder( - FontDataTableBuilderContainer* container, - WritableFontData* data, - int32_t offset, - const CMapId& cmap_id) - : CMapTable::CMap::Builder(container, - data ? down_cast<WritableFontData*>( +CMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, + int32_t offset, + const CMapId& cmap_id) + : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>( data->Slice(offset, data->ReadUShort( offset + Offset::kFormat0Length))) : reinterpret_cast<WritableFontData*>(NULL), @@ -218,13 +213,10 @@ CMapTable::CMapFormat0::Builder::Builder( // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. } -CMapTable::CMapFormat0::Builder::Builder( - FontDataTableBuilderContainer* container, - ReadableFontData* data, - int32_t offset, - const CMapId& cmap_id) - : CMapTable::CMap::Builder(container, - data ? down_cast<ReadableFontData*>( +CMapTable::CMapFormat0::Builder::Builder(ReadableFontData* data, + int32_t offset, + const CMapId& cmap_id) + : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>( data->Slice(offset, data->ReadUShort( offset + Offset::kFormat0Length))) : reinterpret_cast<WritableFontData*>(NULL), @@ -340,13 +332,10 @@ int32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) { /****************************************************************************** * CMapTable::CMapFormat2::Builder ******************************************************************************/ -CMapTable::CMapFormat2::Builder::Builder( - FontDataTableBuilderContainer* container, - WritableFontData* data, - int32_t offset, - const CMapId& cmap_id) - : CMapTable::CMap::Builder(container, - data ? down_cast<WritableFontData*>( +CMapTable::CMapFormat2::Builder::Builder(WritableFontData* data, + int32_t offset, + const CMapId& cmap_id) + : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>( data->Slice(offset, data->ReadUShort( offset + Offset::kFormat0Length))) : reinterpret_cast<WritableFontData*>(NULL), @@ -354,13 +343,10 @@ CMapTable::CMapFormat2::Builder::Builder( // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix. } -CMapTable::CMapFormat2::Builder::Builder( - FontDataTableBuilderContainer* container, - ReadableFontData* data, - int32_t offset, - const CMapId& cmap_id) - : CMapTable::CMap::Builder(container, - data ? down_cast<ReadableFontData*>( +CMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data, + int32_t offset, + const CMapId& cmap_id) + : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>( data->Slice(offset, data->ReadUShort( offset + Offset::kFormat0Length))) : reinterpret_cast<ReadableFontData*>(NULL), @@ -402,16 +388,12 @@ bool CMapTable::CMapIterator::HasNext() { /****************************************************************************** * CMapTable::Builder class ******************************************************************************/ -CMapTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::ArrayElementTableBuilder(font_builder, header, data) { +CMapTable::Builder::Builder(Header* header, WritableFontData* data) + : SubTableContainerTable::Builder(header, data) { } -CMapTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Table::ArrayElementTableBuilder(font_builder, header, data) { +CMapTable::Builder::Builder(Header* header, ReadableFontData* data) + : SubTableContainerTable::Builder(header, data) { } CMapTable::Builder::~Builder() { @@ -483,22 +465,32 @@ CALLER_ATTACH FontDataTable* return table.Detach(); } -CALLER_ATTACH CMapTable::CMap::Builder* CMapTable::Builder::CMapBuilder( - FontDataTableBuilderContainer* container, ReadableFontData* data, - int32_t index) { - if (index < 0 || index > NumCMaps(data)) +CALLER_ATTACH CMapTable::Builder* + CMapTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<CMapTable::Builder> builder; + builder = new CMapTable::Builder(header, data); + return builder.Detach(); +} + +CALLER_ATTACH CMapTable::CMap::Builder* + CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) { + if (index < 0 || index > NumCMaps(data)) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundException( + "CMap table is outside of the bounds of the known tables."); +#endif return NULL; + } - int32_t record_offset = Offset::kEncodingRecordOffset + index * - Offset::kEncodingRecordSize; - int32_t platform_id = - data->ReadUShort(Offset::kEncodingRecordPlatformId + record_offset); - int32_t encoding_id = - data->ReadUShort(Offset::kEncodingRecordEncodingId + record_offset); + int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId + + OffsetForEncodingRecord(index)); + int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId + + OffsetForEncodingRecord(index)); + int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset + + OffsetForEncodingRecord(index)); CMapId cmap_id(platform_id, encoding_id); - int32_t offset = - data->ReadULongAsInt(Offset::kEncodingRecordOffset + record_offset); - return CMap::Builder::GetBuilder(container, data, offset, cmap_id); + return CMap::Builder::GetBuilder(data, offset, cmap_id); } int32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) { diff --git a/sfntly/table/core/cmap_table.h b/sfntly/table/core/cmap_table.h index 76b4266..6455ef6 100644 --- a/sfntly/table/core/cmap_table.h +++ b/sfntly/table/core/cmap_table.h @@ -22,8 +22,8 @@ #include <map> #include "sfntly/port/refcount.h" -#include "sfntly/table/table.h" #include "sfntly/table/subtable.h" +#include "sfntly/table/subtable_container_table.h" namespace sfntly { @@ -43,7 +43,7 @@ struct CMapFormat { }; // A CMap table -class CMapTable : public Table, public RefCounted<CMapTable> { +class CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> { public: // CMapTable::CMapId class CMapId { @@ -113,8 +113,7 @@ public: virtual ~Builder(); CALLER_ATTACH static Builder* - GetBuilder(FontDataTableBuilderContainer* container, - ReadableFontData* data, + GetBuilder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id); @@ -124,12 +123,10 @@ public: virtual int32_t encoding_id() { return cmap_id_.encoding_id(); } protected: - Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data, + Builder(ReadableFontData* data, int32_t format, const CMapId& cmap_id); - Builder(FontDataTableBuilderContainer* container, - WritableFontData* data, + Builder(WritableFontData* data, int32_t format, const CMapId& cmap_id); @@ -186,12 +183,10 @@ public: class Builder : public CMap::Builder, public RefCounted<Builder> { public: - Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data, + Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id); - Builder(FontDataTableBuilderContainer* container, - WritableFontData* data, + Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id); virtual ~Builder(); @@ -218,12 +213,10 @@ public: class Builder : public CMap::Builder, public RefCounted<Builder> { public: - Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data, + Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id); - Builder(FontDataTableBuilderContainer* container, - WritableFontData* data, + Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id); virtual ~Builder(); @@ -254,17 +247,13 @@ public: }; // CMapTable::Builder - class Builder : public Table::ArrayElementTableBuilder, + class Builder : public SubTableContainerTable::Builder, public RefCounted<Builder> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual int32_t SubSerialize(WritableFontData* new_data); @@ -273,11 +262,12 @@ public: virtual void SubDataSet(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + protected: - static CALLER_ATTACH CMap::Builder* - CMapBuilder(FontDataTableBuilderContainer* container, - ReadableFontData* data, - int32_t index); + static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data, + int32_t index); private: static int32_t NumCMaps(ReadableFontData* data); @@ -354,6 +344,7 @@ public: kFormat4EntrySelector = 10, kFormat4RangeShift = 12, kFormat4EndCount = 14, + kFormat4FixedSize = 16, // format 6: Trimmed table mapping kFormat6Format = 0, @@ -437,7 +428,7 @@ public: // Get the offset in the table data for the encoding record for the cmap with // the given index. The offset is from the beginning of the table. - int32_t OffsetForEncodingRecord(int32_t index); + static int32_t OffsetForEncodingRecord(int32_t index); }; typedef std::vector<CMapTable::CMapId> CMapIdList; typedef Ptr<CMapTable> CMapTablePtr; diff --git a/sfntly/table/core/font_header_table.cc b/sfntly/table/core/font_header_table.cc index da19258..3713b02 100644 --- a/sfntly/table/core/font_header_table.cc +++ b/sfntly/table/core/font_header_table.cc @@ -102,14 +102,12 @@ FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data) /****************************************************************************** * FontHeaderTable::Builder class ******************************************************************************/ -FontHeaderTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, WritableFontData* data) : - Table::TableBasedTableBuilder(font_builder, header, data) { +FontHeaderTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } -FontHeaderTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, ReadableFontData* data) : - Table::TableBasedTableBuilder(font_builder, header, data) { +FontHeaderTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } FontHeaderTable::Builder::~Builder() {} @@ -256,4 +254,12 @@ void FontHeaderTable::Builder::SetGlyphDataFormat(int32_t format) { InternalWriteData()->WriteShort(Offset::kGlyphDataFormat, format); } +CALLER_ATTACH FontHeaderTable::Builder* + FontHeaderTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<FontHeaderTable::Builder> builder; + builder = new FontHeaderTable::Builder(header, data); + return builder.Detach(); +} + } // namespace sfntly diff --git a/sfntly/table/core/font_header_table.h b/sfntly/table/core/font_header_table.h index 343e62c..3b20863 100644 --- a/sfntly/table/core/font_header_table.h +++ b/sfntly/table/core/font_header_table.h @@ -45,10 +45,8 @@ class FontHeaderTable : public Table, public RefCounted<FontHeaderTable> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); @@ -90,6 +88,9 @@ class FontHeaderTable : public Table, public RefCounted<FontHeaderTable> { virtual void SetIndexToLocFormat(int32_t format); virtual int32_t GlyphDataFormat(); virtual void SetGlyphDataFormat(int32_t format); + + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); }; virtual ~FontHeaderTable(); diff --git a/sfntly/table/core/horizontal_header_table.cc b/sfntly/table/core/horizontal_header_table.cc index 52b0de2..f07ab01 100644 --- a/sfntly/table/core/horizontal_header_table.cc +++ b/sfntly/table/core/horizontal_header_table.cc @@ -22,7 +22,7 @@ namespace sfntly { ******************************************************************************/ HorizontalHeaderTable:: ~HorizontalHeaderTable() {} -int32_t HorizontalHeaderTable::Version() { +int32_t HorizontalHeaderTable::TableVersion() { return data_->ReadFixed(Offset::kVersion); } @@ -82,18 +82,12 @@ HorizontalHeaderTable:: HorizontalHeaderTable(Header* header, /****************************************************************************** * HorizontalHeaderTable::Builder class ******************************************************************************/ -HorizontalHeaderTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { +HorizontalHeaderTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } -HorizontalHeaderTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { +HorizontalHeaderTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } HorizontalHeaderTable::Builder::~Builder() {} @@ -104,11 +98,19 @@ CALLER_ATTACH FontDataTable* return table.Detach(); } -int32_t HorizontalHeaderTable::Builder::Version() { +CALLER_ATTACH HorizontalHeaderTable::Builder* + HorizontalHeaderTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<HorizontalHeaderTable::Builder> builder; + builder = new HorizontalHeaderTable::Builder(header, data); + return builder.Detach(); +} + +int32_t HorizontalHeaderTable::Builder::TableVersion() { return InternalReadData()->ReadFixed(Offset::kVersion); } -void HorizontalHeaderTable::Builder::SetVersion(int32_t version) { +void HorizontalHeaderTable::Builder::SetTableVersion(int32_t version) { InternalWriteData()->WriteFixed(Offset::kVersion, version); } diff --git a/sfntly/table/core/horizontal_header_table.h b/sfntly/table/core/horizontal_header_table.h index 3a3eb6f..c79a7b6 100644 --- a/sfntly/table/core/horizontal_header_table.h +++ b/sfntly/table/core/horizontal_header_table.h @@ -21,25 +21,26 @@ namespace sfntly { +// A Horizontal Header table - 'hhea'. class HorizontalHeaderTable : public Table, public RefCounted<HorizontalHeaderTable> { public: + // Builder for a Horizontal Header table - 'hhea'. class Builder : public Table::TableBasedTableBuilder, public RefCounted<Builder> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); - int32_t Version(); - void SetVersion(int32_t version); + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + + int32_t TableVersion(); + void SetTableVersion(int32_t version); int32_t Ascender(); void SetAscender(int32_t ascender); int32_t Descender(); @@ -67,7 +68,7 @@ class HorizontalHeaderTable : public Table, }; virtual ~HorizontalHeaderTable(); - int32_t Version(); + int32_t TableVersion(); int32_t Ascender(); int32_t Descender(); int32_t LineGap(); diff --git a/sfntly/table/core/horizontal_metrics_table.cc b/sfntly/table/core/horizontal_metrics_table.cc index b2463b9..67e99e0 100644 --- a/sfntly/table/core/horizontal_metrics_table.cc +++ b/sfntly/table/core/horizontal_metrics_table.cc @@ -33,11 +33,10 @@ int32_t HorizontalMetricsTable::NumberOfLSBs() { int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) { if (entry > num_hmetrics_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException(); #endif + return 0; } int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + Offset::kHMetricsAdvanceWidth; @@ -46,11 +45,10 @@ int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) { int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) { if (entry > num_hmetrics_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException(); #endif + return 0; } int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + Offset::kHMetricsLeftSideBearing; @@ -59,11 +57,10 @@ int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) { int32_t HorizontalMetricsTable::LsbTableEntry(int32_t entry) { if (entry > num_hmetrics_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException(); #endif + return 0; } int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + Offset::kLeftSideBearingSize; @@ -85,11 +82,6 @@ int32_t HorizontalMetricsTable::LeftSideBearing(int32_t glyph_id) { } HorizontalMetricsTable::HorizontalMetricsTable(Header* header, - ReadableFontData* data) - : Table(header, data) { -} - -HorizontalMetricsTable::HorizontalMetricsTable(Header* header, ReadableFontData* data, int32_t num_hmetrics, int32_t num_glyphs) @@ -101,20 +93,16 @@ HorizontalMetricsTable::HorizontalMetricsTable(Header* header, /****************************************************************************** * HorizontalMetricsTable::Builder class ******************************************************************************/ -HorizontalMetricsTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { - Init(); +HorizontalMetricsTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::TableBasedTableBuilder(header, data), + num_hmetrics_(-1), + num_glyphs_(-1) { } -HorizontalMetricsTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { - Init(); +HorizontalMetricsTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::TableBasedTableBuilder(header, data), + num_hmetrics_(-1), + num_glyphs_(-1) { } HorizontalMetricsTable::Builder::~Builder() {} @@ -126,6 +114,14 @@ CALLER_ATTACH FontDataTable* return table.Detach(); } +CALLER_ATTACH HorizontalMetricsTable::Builder* + HorizontalMetricsTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<HorizontalMetricsTable::Builder> builder; + builder = new HorizontalMetricsTable::Builder(header, data); + return builder.Detach(); +} + void HorizontalMetricsTable::Builder::SetNumberOfHMetrics( int32_t num_hmetrics) { assert(num_hmetrics >= 0); @@ -143,9 +139,4 @@ void HorizontalMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) { table->num_glyphs_ = num_glyphs; } -void HorizontalMetricsTable::Builder::Init() { - num_hmetrics_ = -1; - num_glyphs_ = -1; -} - } // namespace sfntly diff --git a/sfntly/table/core/horizontal_metrics_table.h b/sfntly/table/core/horizontal_metrics_table.h index aa3fa65..eaf79e4 100644 --- a/sfntly/table/core/horizontal_metrics_table.h +++ b/sfntly/table/core/horizontal_metrics_table.h @@ -21,29 +21,28 @@ namespace sfntly { +// A Horizontal Metrics table - 'hmtx'. class HorizontalMetricsTable : public Table, public RefCounted<HorizontalMetricsTable> { public: + // Builder for a Horizontal Metrics Table - 'hmtx'. class Builder : public Table::TableBasedTableBuilder, public RefCounted<Builder> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + void SetNumberOfHMetrics(int32_t num_hmetrics); void SetNumGlyphs(int32_t num_glyphs); private: - void Init(); - int32_t num_hmetrics_; int32_t num_glyphs_; }; @@ -72,7 +71,6 @@ class HorizontalMetricsTable : public Table, }; }; - HorizontalMetricsTable(Header* header, ReadableFontData* data); HorizontalMetricsTable(Header* header, ReadableFontData* data, int32_t num_hmetrics, diff --git a/sfntly/table/core/maximum_profile_table.cc b/sfntly/table/core/maximum_profile_table.cc index fec508a..e457621 100644 --- a/sfntly/table/core/maximum_profile_table.cc +++ b/sfntly/table/core/maximum_profile_table.cc @@ -22,7 +22,7 @@ namespace sfntly { ******************************************************************************/ MaximumProfileTable::~MaximumProfileTable() {} -int32_t MaximumProfileTable::Version() { +int32_t MaximumProfileTable::TableVersion() { return data_->ReadFixed(Offset::kVersion); } @@ -42,6 +42,10 @@ int32_t MaximumProfileTable::MaxCompositePoints() { return data_->ReadUShort(Offset::kMaxCompositePoints); } +int32_t MaximumProfileTable::MaxCompositeContours() { + return data_->ReadUShort(Offset::kMaxCompositeContours); +} + int32_t MaximumProfileTable::MaxZones() { return data_->ReadUShort(Offset::kMaxZones); } @@ -82,18 +86,12 @@ MaximumProfileTable::MaximumProfileTable(Header* header, /****************************************************************************** * MaximumProfileTable::Builder class ******************************************************************************/ -MaximumProfileTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { +MaximumProfileTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } -MaximumProfileTable::Builder::Builder( - FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Table::TableBasedTableBuilder(font_builder, header, data) { +MaximumProfileTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::TableBasedTableBuilder(header, data) { } MaximumProfileTable::Builder::~Builder() {} @@ -104,11 +102,19 @@ CALLER_ATTACH FontDataTable* return table.Detach(); } -int32_t MaximumProfileTable::Builder::Version() { +CALLER_ATTACH MaximumProfileTable::Builder* + MaximumProfileTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<MaximumProfileTable::Builder> builder; + builder = new MaximumProfileTable::Builder(header, data); + return builder.Detach(); +} + +int32_t MaximumProfileTable::Builder::TableVersion() { return InternalReadData()->ReadUShort(Offset::kVersion); } -void MaximumProfileTable::Builder::SetVersion(int32_t version) { +void MaximumProfileTable::Builder::SetTableVersion(int32_t version) { InternalWriteData()->WriteUShort(Offset::kVersion, version); } @@ -146,6 +152,16 @@ void MaximumProfileTable::Builder::SetMaxCompositePoints( max_composite_points); } +int32_t MaximumProfileTable::Builder::MaxCompositeContours() { + return InternalReadData()->ReadUShort(Offset::kMaxCompositeContours); +} + +void MaximumProfileTable::Builder::SetMaxCompositeContours( + int32_t max_composite_contours) { + InternalWriteData()->WriteUShort(Offset::kMaxCompositeContours, + max_composite_contours); +} + int32_t MaximumProfileTable::Builder::MaxZones() { return InternalReadData()->ReadUShort(Offset::kMaxZones); } diff --git a/sfntly/table/core/maximum_profile_table.h b/sfntly/table/core/maximum_profile_table.h index 10ec872..9b89617 100644 --- a/sfntly/table/core/maximum_profile_table.h +++ b/sfntly/table/core/maximum_profile_table.h @@ -22,24 +22,26 @@ namespace sfntly { +// A Maximum Profile table - 'maxp'. class MaximumProfileTable : public Table, public RefCounted<MaximumProfileTable> { public: + // Builder for a Maximum Profile table - 'maxp'. class Builder : public Table::TableBasedTableBuilder, public RefCounted<Builder> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); - int32_t Version(); - void SetVersion(int32_t version); + int32_t TableVersion(); + void SetTableVersion(int32_t version); int32_t NumGlyphs(); void SetNumGlyphs(int32_t num_glyphs); int32_t MaxPoints(); @@ -48,6 +50,8 @@ class MaximumProfileTable : public Table, void SetMaxContours(int32_t max_contours); int32_t MaxCompositePoints(); void SetMaxCompositePoints(int32_t max_composite_points); + int32_t MaxCompositeContours(); + void SetMaxCompositeContours(int32_t max_composite_contours); int32_t MaxZones(); void SetMaxZones(int32_t max_zones); int32_t MaxTwilightPoints(); @@ -67,11 +71,12 @@ class MaximumProfileTable : public Table, }; virtual ~MaximumProfileTable(); - int32_t Version(); + int32_t TableVersion(); int32_t NumGlyphs(); int32_t MaxPoints(); int32_t MaxContours(); int32_t MaxCompositePoints(); + int32_t MaxCompositeContours(); int32_t MaxZones(); int32_t MaxTwilightPoints(); int32_t MaxStorage(); diff --git a/sfntly/table/core/name_table.cc b/sfntly/table/core/name_table.cc index 00c4519..9853130 100644 --- a/sfntly/table/core/name_table.cc +++ b/sfntly/table/core/name_table.cc @@ -137,8 +137,8 @@ NameTable::NameEntryBuilder::NameEntryBuilder() { Init(0, 0, 0, 0, NULL); } -NameTable::NameEntryBuilder::NameEntryBuilder( - const NameEntryId& name_entry_id, const ByteVector& name_bytes) { +NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id, + const ByteVector& name_bytes) { Init(name_entry_id.platform_id(), name_entry_id.encoding_id(), name_entry_id.language_id(), @@ -263,7 +263,7 @@ CALLER_ATTACH NameTable::NameEntry* NameTable::NameEntryIterator::Next() { void NameTable::NameEntryIterator::Remove() { #if !defined (SFNTLY_NO_EXCEPTION) throw UnsupportedOperationException( - "Cannot remove a CMap table from an existing font."); + "Cannot remove a name table from an existing font."); #endif } @@ -277,16 +277,20 @@ void NameTable::NameEntryIterator::Init(NameTable* table, /****************************************************************************** * NameTable::Builder class ******************************************************************************/ -NameTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::ArrayElementTableBuilder(font_builder, header, data) { +NameTable::Builder::Builder(Header* header, WritableFontData* data) + : SubTableContainerTable::Builder(header, data) { +} + +NameTable::Builder::Builder(Header* header, ReadableFontData* data) + : SubTableContainerTable::Builder(header, data) { } -NameTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Table::ArrayElementTableBuilder(font_builder, header, data) { +CALLER_ATTACH NameTable::Builder* + NameTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<NameTable::Builder> builder; + builder = new NameTable::Builder(header, data); + return builder.Detach(); } void NameTable::Builder::RevertNames() { @@ -546,7 +550,7 @@ NameTable::NameEntryIterator* NameTable::Iterator(NameEntryFilter* filter) { } NameTable::NameTable(Header* header, ReadableFontData* data) - : Table(header, data) {} + : SubTableContainerTable(header, data) {} int32_t NameTable::StringOffset() { return data_->ReadUShort(Offset::kStringOffset); diff --git a/sfntly/table/core/name_table.h b/sfntly/table/core/name_table.h index b5a7f9a..0c657da 100644 --- a/sfntly/table/core/name_table.h +++ b/sfntly/table/core/name_table.h @@ -26,7 +26,7 @@ #include <map> #include <utility> -#include "sfntly/table/table.h" +#include "sfntly/table/subtable_container_table.h" #if defined U_USING_ICU_NAMESPACE U_NAMESPACE_USE @@ -412,7 +412,7 @@ struct WindowsLanguageId { }; }; -class NameTable : public Table, public RefCounted<NameTable> { +class NameTable : public SubTableContainerTable, public RefCounted<NameTable> { public: // Unique identifier for a given name record. class NameEntryId { @@ -433,6 +433,9 @@ class NameTable : public Table, public RefCounted<NameTable> { bool operator==(const NameEntryId& rhs) const; bool operator<(const NameEntryId& rhs) const; + // UNIMPLEMENTED: int hashCode() + // String toString() + private: mutable int32_t platform_id_; mutable int32_t encoding_id_; @@ -447,8 +450,11 @@ class NameTable : public Table, public RefCounted<NameTable> { public: NameEntry(); NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes); - NameEntry(int32_t platform_id, int32_t encoding_id, int32_t language_id, - int32_t name_id, const ByteVector& name_bytes); + NameEntry(int32_t platform_id, + int32_t encoding_id, + int32_t language_id, + int32_t name_id, + const ByteVector& name_bytes); virtual ~NameEntry(); NameEntryId& name_entry_id() { return name_entry_id_; } @@ -469,6 +475,9 @@ class NameTable : public Table, public RefCounted<NameTable> { UChar* Name(); bool operator==(const NameEntry& rhs) const; + // UNIMPLEMENTED: String toString() + // int hashCode() + private: void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id, int32_t name_id, const ByteVector* name_bytes); @@ -494,7 +503,8 @@ class NameTable : public Table, public RefCounted<NameTable> { virtual void SetName(const UChar* name); virtual void SetName(const ByteVector& name_bytes); - virtual void SetName(const ByteVector& name_bytes, int32_t offset, + virtual void SetName(const ByteVector& name_bytes, + int32_t offset, int32_t length); // C++ port only. CALLER_ATTACH is not added because the lifetime shall be @@ -515,8 +525,10 @@ class NameTable : public Table, public RefCounted<NameTable> { // returned. class NameEntryFilter { public: - virtual bool Accept(int32_t platform_id, int32_t encoding_id, - int32_t language_id, int32_t name_id) = 0; + virtual bool Accept(int32_t platform_id, + int32_t encoding_id, + int32_t language_id, + int32_t name_id) = 0; // Make gcc -Wnon-virtual-dtor happy. virtual ~NameEntryFilter() {} }; @@ -524,13 +536,17 @@ class NameTable : public Table, public RefCounted<NameTable> { // C++ port only: an in-place filter to mimic Java Iterator's filtering. class NameEntryFilterInPlace : public NameEntryFilter { public: - NameEntryFilterInPlace(int32_t platform_id, int32_t encoding_id, - int32_t language_id, int32_t name_id); + NameEntryFilterInPlace(int32_t platform_id, + int32_t encoding_id, + int32_t language_id, + int32_t name_id); // Make gcc -Wnon-virtual-dtor happy. virtual ~NameEntryFilterInPlace() {} - virtual bool Accept(int32_t platform_id, int32_t encoding_id, - int32_t language_id, int32_t name_id); + virtual bool Accept(int32_t platform_id, + int32_t encoding_id, + int32_t language_id, + int32_t name_id); private: int32_t platform_id_; @@ -561,15 +577,16 @@ class NameTable : public Table, public RefCounted<NameTable> { }; // The builder to construct name table for outputting. - class Builder : public Table::ArrayElementTableBuilder, + class Builder : public SubTableContainerTable::Builder, public RefCounted<Builder> { public: // Constructor scope altered to public because C++ does not allow base // class to instantiate derived class with protected constructors. - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); + + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); // Revert the name builders for the name table to the last version that came // from data. diff --git a/sfntly/table/core/os2_table.cc b/sfntly/table/core/os2_table.cc index 8ab435b..024b03a 100644 --- a/sfntly/table/core/os2_table.cc +++ b/sfntly/table/core/os2_table.cc @@ -100,7 +100,7 @@ int32_t UnicodeRange::range(int32_t bit) { ******************************************************************************/ OS2Table::~OS2Table() {} -int32_t OS2Table::Version() { +int32_t OS2Table::TableVersion() { return data_->ReadUShort(Offset::kVersion); } @@ -165,6 +165,7 @@ int32_t OS2Table::SFamilyClass() { } void OS2Table::Panose(ByteVector* value) { + assert(value); value->clear(); value->resize(10); data_->ReadBytes(Offset::kPanose, &((*value)[0]), 0, 10); @@ -187,6 +188,7 @@ int64_t OS2Table::UlUnicodeRange4() { } void OS2Table::AchVendId(ByteVector* b) { + assert(b); b->clear(); b->resize(4); data_->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4); @@ -232,16 +234,14 @@ int64_t OS2Table::UlCodePageRange2() { return data_->ReadULong(Offset::kUlCodePageRange2); } -int64_t OS2Table::UlCodePageRange() { - // TODO(arthurhsu): Possible bug point, check with stuartg. - return ((0xffffffff & UlCodePageRange2()) << 32) | - (0xffffffff & UlCodePageRange1()); -} - int32_t OS2Table::SxHeight() { return data_->ReadShort(Offset::kSxHeight); } +int32_t OS2Table::SCapHeight() { + return data_->ReadShort(Offset::kSCapHeight); +} + int32_t OS2Table::UsDefaultChar() { return data_->ReadUShort(Offset::kUsDefaultChar); } @@ -261,9 +261,12 @@ OS2Table::OS2Table(Header* header, ReadableFontData* data) /****************************************************************************** * class OS2Table::Builder ******************************************************************************/ -OS2Table::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, WritableFontData* data) : - Table::TableBasedTableBuilder(font_builder, header, data) { +OS2Table::Builder::Builder(Header* header, WritableFontData* data) : + Table::TableBasedTableBuilder(header, data) { +} + +OS2Table::Builder::Builder(Header* header, ReadableFontData* data) : + Table::TableBasedTableBuilder(header, data) { } OS2Table::Builder::~Builder() {} @@ -274,4 +277,331 @@ CALLER_ATTACH FontDataTable* OS2Table::Builder::SubBuildTable( return table.Detach(); } +CALLER_ATTACH OS2Table::Builder* + OS2Table::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<OS2Table::Builder> builder; + builder = new OS2Table::Builder(header, data); + return builder.Detach(); +} + +int32_t OS2Table::Builder::TableVersion() { + return InternalReadData()->ReadUShort(Offset::kVersion); +} + +void OS2Table::Builder::SetTableVersion(int32_t version) { + InternalWriteData()->WriteUShort(Offset::kVersion, version); +} + +int32_t OS2Table::Builder::XAvgCharWidth() { + return InternalReadData()->ReadShort(Offset::kXAvgCharWidth); +} + +void OS2Table::Builder::SetXAvgCharWidth(int32_t width) { + InternalWriteData()->WriteShort(Offset::kXAvgCharWidth, width); +} + +int32_t OS2Table::Builder::UsWeightClass() { + return InternalReadData()->ReadUShort(Offset::kUsWeightClass); +} + +void OS2Table::Builder::SetUsWeightClass(int32_t weight) { + InternalWriteData()->WriteUShort(Offset::kUsWeightClass, weight); +} + +int32_t OS2Table::Builder::UsWidthClass() { + return InternalReadData()->ReadUShort(Offset::kUsWidthClass); +} + +void OS2Table::Builder::SetUsWidthClass(int32_t width) { + InternalWriteData()->WriteUShort(Offset::kUsWidthClass, width); +} + +int32_t OS2Table::Builder::FsType() { + return InternalReadData()->ReadUShort(Offset::kFsType); +} + +void OS2Table::Builder::SetFsType(int32_t fs_type) { + InternalWriteData()->WriteUShort(Offset::kFsType, fs_type); +} + +int32_t OS2Table::Builder::YSubscriptXSize() { + return InternalReadData()->ReadShort(Offset::kYSubscriptXSize); +} + +void OS2Table::Builder::SetYSubscriptXSize(int32_t size) { + InternalWriteData()->WriteShort(Offset::kYSubscriptXSize, size); +} + +int32_t OS2Table::Builder::YSubscriptYSize() { + return InternalReadData()->ReadShort(Offset::kYSubscriptYSize); +} + +void OS2Table::Builder::SetYSubscriptYSize(int32_t size) { + InternalWriteData()->WriteShort(Offset::kYSubscriptYSize, size); +} + +int32_t OS2Table::Builder::YSubscriptXOffset() { + return InternalReadData()->ReadShort(Offset::kYSubscriptXOffset); +} + +void OS2Table::Builder::SetYSubscriptXOffset(int32_t offset) { + InternalWriteData()->WriteShort(Offset::kYSubscriptXOffset, offset); +} + +int32_t OS2Table::Builder::YSubscriptYOffset() { + return InternalReadData()->ReadShort(Offset::kYSubscriptYOffset); +} + +void OS2Table::Builder::SetYSubscriptYOffset(int32_t offset) { + InternalWriteData()->WriteShort(Offset::kYSubscriptYOffset, offset); +} + +int32_t OS2Table::Builder::YSuperscriptXSize() { + return InternalReadData()->ReadShort(Offset::kYSuperscriptXSize); +} + +void OS2Table::Builder::SetYSuperscriptXSize(int32_t size) { + InternalWriteData()->WriteShort(Offset::kYSuperscriptXSize, size); +} + +int32_t OS2Table::Builder::YSuperscriptYSize() { + return InternalReadData()->ReadShort(Offset::kYSuperscriptYSize); +} + +void OS2Table::Builder::SetYSuperscriptYSize(int32_t size) { + InternalWriteData()->WriteShort(Offset::kYSuperscriptYSize, size); +} + +int32_t OS2Table::Builder::YSuperscriptXOffset() { + return InternalReadData()->ReadShort(Offset::kYSuperscriptXOffset); +} + +void OS2Table::Builder::SetYSuperscriptXOffset(int32_t offset) { + InternalWriteData()->WriteShort(Offset::kYSuperscriptXOffset, offset); +} + +int32_t OS2Table::Builder::YSuperscriptYOffset() { + return InternalReadData()->ReadShort(Offset::kYSuperscriptYOffset); +} + +void OS2Table::Builder::SetYSuperscriptYOffset(int32_t offset) { + InternalWriteData()->WriteShort(Offset::kYSuperscriptYOffset, offset); +} + +int32_t OS2Table::Builder::YStrikeoutSize() { + return InternalReadData()->ReadShort(Offset::kYStrikeoutSize); +} + +void OS2Table::Builder::SetYStrikeoutSize(int32_t size) { + InternalWriteData()->WriteShort(Offset::kYStrikeoutSize, size); +} + +int32_t OS2Table::Builder::YStrikeoutPosition() { + return InternalReadData()->ReadShort(Offset::kYStrikeoutPosition); +} + +void OS2Table::Builder::SetYStrikeoutPosition(int32_t position) { + InternalWriteData()->WriteShort(Offset::kYStrikeoutPosition, position); +} + +int32_t OS2Table::Builder::SFamilyClass() { + return InternalReadData()->ReadShort(Offset::kSFamilyClass); +} + +void OS2Table::Builder::SetSFamilyClass(int32_t family) { + InternalWriteData()->WriteShort(Offset::kSFamilyClass, family); +} + +void OS2Table::Builder::Panose(ByteVector* value) { + assert(value); + value->clear(); + value->resize(Offset::kPanoseLength); + InternalReadData()->ReadBytes(Offset::kPanose, + &((*value)[0]), + 0, + Offset::kPanoseLength); +} + +void OS2Table::Builder::SetPanose(ByteVector* panose) { + assert(panose); + if (panose->size() != Offset::kPanoseLength) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IllegalArgumentException("Panose bytes must be exactly 10 in length"); +#endif + return; + } + InternalWriteData()->WriteBytes(Offset::kPanose, panose); +} + +int64_t OS2Table::Builder::UlUnicodeRange1() { + return InternalReadData()->ReadULong(Offset::kUlUnicodeRange1); +} + +void OS2Table::Builder::SetUlUnicodeRange1(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlUnicodeRange1, range); +} + +int64_t OS2Table::Builder::UlUnicodeRange2() { + return InternalReadData()->ReadULong(Offset::kUlUnicodeRange2); +} + +void OS2Table::Builder::SetUlUnicodeRange2(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlUnicodeRange2, range); +} + +int64_t OS2Table::Builder::UlUnicodeRange3() { + return InternalReadData()->ReadULong(Offset::kUlUnicodeRange3); +} + +void OS2Table::Builder::SetUlUnicodeRange3(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlUnicodeRange3, range); +} + +int64_t OS2Table::Builder::UlUnicodeRange4() { + return InternalReadData()->ReadULong(Offset::kUlUnicodeRange4); +} + +void OS2Table::Builder::SetUlUnicodeRange4(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range); +} + +void OS2Table::Builder::AchVendId(ByteVector* b) { + assert(b); + b->clear(); + b->resize(4); + InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4); +} + +void OS2Table::Builder::SetAchVendId(ByteVector* b) { + assert(b); + assert(b->size()); + InternalWriteData()->WriteBytes(Offset::kAchVendId, + &((*b)[0]), + 0, + std::min<size_t>( + (size_t)Offset::kAchVendIdLength, + b->size())); +} + +int32_t OS2Table::Builder::FsSelection() { + return InternalReadData()->ReadUShort(Offset::kFsSelection); +} + +void OS2Table::Builder::SetFsSelection(int32_t fs_selection) { + InternalWriteData()->WriteUShort(Offset::kFsSelection, fs_selection); +} + +int32_t OS2Table::Builder::UsFirstCharIndex() { + return InternalReadData()->ReadUShort(Offset::kUsFirstCharIndex); +} + +void OS2Table::Builder::SetUsFirstCharIndex(int32_t first_index) { + InternalWriteData()->WriteUShort(Offset::kUsFirstCharIndex, first_index); +} + +int32_t OS2Table::Builder::UsLastCharIndex() { + return InternalReadData()->ReadUShort(Offset::kUsLastCharIndex); +} + +void OS2Table::Builder::SetUsLastCharIndex(int32_t last_index) { + InternalWriteData()->WriteUShort(Offset::kUsLastCharIndex, last_index); +} + +int32_t OS2Table::Builder::STypoAscender() { + return InternalReadData()->ReadShort(Offset::kSTypoAscender); +} + +void OS2Table::Builder::SetSTypoAscender(int32_t ascender) { + InternalWriteData()->WriteShort(Offset::kSTypoAscender, ascender); +} + +int32_t OS2Table::Builder::STypoDescender() { + return InternalReadData()->ReadShort(Offset::kSTypoDescender); +} + +void OS2Table::Builder::SetSTypoDescender(int32_t descender) { + InternalWriteData()->WriteShort(Offset::kSTypoDescender, descender); +} + +int32_t OS2Table::Builder::STypoLineGap() { + return InternalReadData()->ReadShort(Offset::kSTypoLineGap); +} + +void OS2Table::Builder::SetSTypoLineGap(int32_t line_gap) { + InternalWriteData()->WriteShort(Offset::kSTypoLineGap, line_gap); +} + +int32_t OS2Table::Builder::UsWinAscent() { + return InternalReadData()->ReadUShort(Offset::kUsWinAscent); +} + +void OS2Table::Builder::SetUsWinAscent(int32_t ascent) { + InternalWriteData()->WriteUShort(Offset::kUsWinAscent, ascent); +} + +int32_t OS2Table::Builder::UsWinDescent() { + return InternalReadData()->ReadUShort(Offset::kUsWinDescent); +} + +void OS2Table::Builder::SetUsWinDescent(int32_t descent) { + InternalWriteData()->WriteUShort(Offset::kUsWinDescent, descent); +} + +int64_t OS2Table::Builder::UlCodePageRange1() { + return InternalReadData()->ReadULong(Offset::kUlCodePageRange1); +} + +void OS2Table::Builder::SetUlCodePageRange1(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlCodePageRange1, range); +} + +int64_t OS2Table::Builder::UlCodePageRange2() { + return InternalReadData()->ReadULong(Offset::kUlCodePageRange2); +} + +void OS2Table::Builder::SetUlCodePageRange2(int64_t range) { + InternalWriteData()->WriteULong(Offset::kUlCodePageRange2, range); +} + +int32_t OS2Table::Builder::SxHeight() { + return InternalReadData()->ReadShort(Offset::kSxHeight); +} + +void OS2Table::Builder::SetSxHeight(int32_t height) { + InternalWriteData()->WriteShort(Offset::kSxHeight, height); +} + +int32_t OS2Table::Builder::SCapHeight() { + return InternalReadData()->ReadShort(Offset::kSCapHeight); +} + +void OS2Table::Builder::SetSCapHeight(int32_t height) { + InternalWriteData()->WriteShort(Offset::kSCapHeight, height); +} + +int32_t OS2Table::Builder::UsDefaultChar() { + return InternalReadData()->ReadUShort(Offset::kUsDefaultChar); +} + +void OS2Table::Builder::SetUsDefaultChar(int32_t default_char) { + InternalWriteData()->WriteUShort(Offset::kUsDefaultChar, default_char); +} + +int32_t OS2Table::Builder::UsBreakChar() { + return InternalReadData()->ReadUShort(Offset::kUsBreakChar); +} + +void OS2Table::Builder::SetUsBreakChar(int32_t break_char) { + InternalWriteData()->WriteUShort(Offset::kUsBreakChar, break_char); +} + +int32_t OS2Table::Builder::UsMaxContext() { + return InternalReadData()->ReadUShort(Offset::kUsMaxContext); +} + +void OS2Table::Builder::SetUsMaxContext(int32_t max_context) { + InternalWriteData()->WriteUShort(Offset::kUsMaxContext, max_context); +} + } // namespace sfntly diff --git a/sfntly/table/core/os2_table.h b/sfntly/table/core/os2_table.h index 24b6027..cd34ff8 100644 --- a/sfntly/table/core/os2_table.h +++ b/sfntly/table/core/os2_table.h @@ -56,6 +56,7 @@ struct WidthClass { }; }; +// Flags to indicate the embedding licensing rights for a font. struct EmbeddingFlags { enum { kReserved0 = 1 << 0, @@ -79,8 +80,8 @@ struct EmbeddingFlags { struct UnicodeRange { enum { - // This enum relies on the ordering of the data matching the ordinal numbers - // of the properties. + // Do NOT reorder. This enum relies on the ordering of the data matching the + // ordinal numbers of the properties. kBasicLatin, kLatin1Supplement, kLatinExtendedA, @@ -213,6 +214,7 @@ struct UnicodeRange { int32_t range(int32_t bit); // UNIMPLEMENTED: EnumSet<UnicodeRange> asSet(long range1, long range2, // long range3, long range4) + // long[] asArray(EnumSet<UnicodeRange> rangeSet) }; struct FsSelection { @@ -228,6 +230,9 @@ struct FsSelection { kWWS = 1 << 8, kOBLIQUE = 1 << 9 }; + // UNIMPLEMENTED: EnumSet<FsSelection> asSet(long range1, long range2, + // long range3, long range4) + // long[] asArray(EnumSet<FsSelection> rangeSet) }; // C++ port only: C++ does not support 64-bit enums until C++0x. For better @@ -297,22 +302,113 @@ struct CodePageRange { static const int64_t kArabic_708; static const int64_t kLatin1_850; static const int64_t kUS_437; + + // UNIMPLEMENTED: EnumSet<CodePageRange> asSet(long range1, long range2, + // long range3, long range4) + // long[] asArray(EnumSet<CodePageRange> rangeSet) }; +// An OS/2 table - 'OS/2'. class OS2Table : public Table, public RefCounted<OS2Table> { public: + // A builder for the OS/2 table = 'OS/2'. class Builder : public Table::TableBasedTableBuilder, public RefCounted<Builder> { public: - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - WritableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); + + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + + int32_t TableVersion(); + void SetTableVersion(int32_t version); + int32_t XAvgCharWidth(); + void SetXAvgCharWidth(int32_t width); + int32_t UsWeightClass(); + void SetUsWeightClass(int32_t weight); + int32_t UsWidthClass(); + void SetUsWidthClass(int32_t width); + // UNIMPLEMENTED: EnumSet<EmbeddingFlags> fsType() + // void setFsType(EnumSeT<EmbeddingFlags> flagSet) + int32_t FsType(); + void SetFsType(int32_t fs_type); + int32_t YSubscriptXSize(); + void SetYSubscriptXSize(int32_t size); + int32_t YSubscriptYSize(); + void SetYSubscriptYSize(int32_t size); + int32_t YSubscriptXOffset(); + void SetYSubscriptXOffset(int32_t offset); + int32_t YSubscriptYOffset(); + void SetYSubscriptYOffset(int32_t offset); + int32_t YSuperscriptXSize(); + void SetYSuperscriptXSize(int32_t size); + int32_t YSuperscriptYSize(); + void SetYSuperscriptYSize(int32_t size); + int32_t YSuperscriptXOffset(); + void SetYSuperscriptXOffset(int32_t offset); + int32_t YSuperscriptYOffset(); + void SetYSuperscriptYOffset(int32_t offset); + int32_t YStrikeoutSize(); + void SetYStrikeoutSize(int32_t size); + int32_t YStrikeoutPosition(); + void SetYStrikeoutPosition(int32_t position); + int32_t SFamilyClass(); + void SetSFamilyClass(int32_t family); + void Panose(ByteVector* value); + void SetPanose(ByteVector* panose); + int64_t UlUnicodeRange1(); + void SetUlUnicodeRange1(int64_t range); + int64_t UlUnicodeRange2(); + void SetUlUnicodeRange2(int64_t range); + int64_t UlUnicodeRange3(); + void SetUlUnicodeRange3(int64_t range); + int64_t UlUnicodeRange4(); + void SetUlUnicodeRange4(int64_t range); + // UNIMPLEMENTED: EnumSet<UnicodeRange> UlUnicodeRange() + // setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet) + void AchVendId(ByteVector* b); + void SetAchVendId(ByteVector* b); + // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection() + int32_t FsSelection(); + void SetFsSelection(int32_t fs_selection); + int32_t UsFirstCharIndex(); + void SetUsFirstCharIndex(int32_t first_index); + int32_t UsLastCharIndex(); + void SetUsLastCharIndex(int32_t last_index); + int32_t STypoAscender(); + void SetSTypoAscender(int32_t ascender); + int32_t STypoDescender(); + void SetSTypoDescender(int32_t descender); + int32_t STypoLineGap(); + void SetSTypoLineGap(int32_t line_gap); + int32_t UsWinAscent(); + void SetUsWinAscent(int32_t ascent); + int32_t UsWinDescent(); + void SetUsWinDescent(int32_t descent); + int64_t UlCodePageRange1(); + void SetUlCodePageRange1(int64_t range); + int64_t UlCodePageRange2(); + void SetUlCodePageRange2(int64_t range); + // UNIMPLEMENTED: EnumSet<CodePageRange> ulCodePageRange() + // void setUlCodePageRange(EnumSet<CodePageRange> rangeSet) + int32_t SxHeight(); + void SetSxHeight(int32_t height); + int32_t SCapHeight(); + void SetSCapHeight(int32_t height); + int32_t UsDefaultChar(); + void SetUsDefaultChar(int32_t default_char); + int32_t UsBreakChar(); + void SetUsBreakChar(int32_t break_char); + int32_t UsMaxContext(); + void SetUsMaxContext(int32_t max_context); }; ~OS2Table(); - int32_t Version(); + int32_t TableVersion(); int32_t XAvgCharWidth(); int32_t UsWeightClass(); int32_t UsWidthClass(); @@ -348,7 +444,6 @@ class OS2Table : public Table, public RefCounted<OS2Table> { int64_t UlCodePageRange1(); int64_t UlCodePageRange2(); // UNIMPLEMENTED: public EnumSet<CodePageRange> ulCodePageRange() - int64_t UlCodePageRange(); int32_t SxHeight(); int32_t SCapHeight(); int32_t UsDefaultChar(); @@ -375,11 +470,13 @@ class OS2Table : public Table, public RefCounted<OS2Table> { kYStrikeoutPosition = 28, kSFamilyClass = 30, kPanose = 32, + kPanoseLength = 10, // Length of panose bytes. kUlUnicodeRange1 = 42, kUlUnicodeRange2 = 46, kUlUnicodeRange3 = 50, kUlUnicodeRange4 = 54, kAchVendId = 58, + kAchVendIdLength = 4, // Length of ach vend id bytes. kFsSelection = 62, kUsFirstCharIndex = 64, kUsLastCharIndex = 66, diff --git a/sfntly/table/font_data_table.cc b/sfntly/table/font_data_table.cc index 7be3f77..d662e42 100644 --- a/sfntly/table/font_data_table.cc +++ b/sfntly/table/font_data_table.cc @@ -34,23 +34,18 @@ ReadableFontData* FontDataTable::ReadFontData() { return data_; } -int32_t FontDataTable::Length() { - return data_->Length(); -} - -int32_t FontDataTable::Padding() { - return -1; -} - int32_t FontDataTable::DataLength() { - int32_t paddings = Padding(); - return (paddings == -1) ? Length() : Length() - paddings; + return data_->Length(); } int32_t FontDataTable::Serialize(OutputStream* os) { return data_->CopyTo(os); } +int32_t FontDataTable::Serialize(WritableFontData* data) { + return data_->CopyTo(data); +} + /****************************************************************************** * FontDataTable::Builder class ******************************************************************************/ @@ -61,11 +56,12 @@ CALLER_ATTACH WritableFontData* FontDataTable::Builder::Data() { return NULL; } int32_t size = SubDataSizeToSerialize(); - new_data.Attach(container_->GetNewData(size)); + new_data.Attach(WritableFontData::CreateWritableFontData(size)); SubSerialize(new_data); } else { ReadableFontDataPtr data = InternalReadData(); - new_data.Attach(container_->GetNewData(data != NULL ? data->Length() : 0)); + new_data.Attach(WritableFontData::CreateWritableFontData( + data != NULL ? data->Length() : 0)); data->CopyTo(new_data); } return new_data.Detach(); @@ -85,7 +81,7 @@ CALLER_ATTACH FontDataTable* FontDataTable::Builder::Build() { } int32_t size = SubDataSizeToSerialize(); WritableFontDataPtr new_data; - new_data.Attach(container_->GetNewData(size)); + new_data.Attach(WritableFontData::CreateWritableFontData(size)); SubSerialize(new_data); data = new_data; } @@ -111,43 +107,32 @@ ReadableFontData* FontDataTable::Builder::InternalReadData() { WritableFontData* FontDataTable::Builder::InternalWriteData() { if (w_data_ == NULL) { WritableFontDataPtr new_data; - new_data.Attach(container_->GetNewData(r_data_->Length())); - r_data_->CopyTo(new_data); + new_data.Attach(WritableFontData::CreateWritableFontData( + r_data_ == NULL ? 0 : r_data_->Length())); + if (r_data_) { + r_data_->CopyTo(new_data); + } InternalSetData(new_data, false); } return w_data_.p_; } -CALLER_ATTACH WritableFontData* - FontDataTable::Builder::InternalNewData(int32_t size) { - return container_->GetNewData(size); -} - -FontDataTable::Builder::Builder(FontDataTableBuilderContainer* container) { - Init(container); +FontDataTable::Builder::Builder() { } -FontDataTable::Builder::Builder(FontDataTableBuilderContainer* container, - WritableFontData* data) { - Init(container); +FontDataTable::Builder::Builder(WritableFontData* data) + : model_changed_(false), data_changed_(false) { w_data_ = data; } -FontDataTable::Builder::Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data) { - Init(container); +FontDataTable::Builder::Builder(ReadableFontData* data) + : model_changed_(false), data_changed_(false) { r_data_ = data; } FontDataTable::Builder::~Builder() { } -void FontDataTable::Builder::Init(FontDataTableBuilderContainer* container) { - container_ = container; - model_changed_ = false; - data_changed_ = false; -} - void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) { // Default: NOP. UNREFERENCED_PARAMETER(table); diff --git a/sfntly/table/font_data_table.h b/sfntly/table/font_data_table.h index a2b026f..ce5433b 100644 --- a/sfntly/table/font_data_table.h +++ b/sfntly/table/font_data_table.h @@ -18,11 +18,13 @@ #define SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_ #include "sfntly/data/readable_font_data.h" -#include "sfntly/font_data_table_builder_container.h" +#include "sfntly/data/writable_font_data.h" #include "sfntly/port/refcount.h" namespace sfntly { +// An abstract base for any table that contains a FontData. This is the root of +// the table class hierarchy. class FontDataTable : virtual public RefCount { public: // Note: original version is abstract Builder<T extends FontDataTable> @@ -45,10 +47,14 @@ class FontDataTable : virtual public RefCount { ReadableFontData* InternalReadData(); WritableFontData* InternalWriteData(); - CALLER_ATTACH WritableFontData* InternalNewData(int32_t size); bool data_changed() { return data_changed_; } - bool model_changed() { return model_changed_; } + bool model_changed() { + return current_model_changed() || contained_model_changed(); + } + bool current_model_changed() { return model_changed_; } + bool contained_model_changed() { return contained_model_changed_; } + bool set_model_changed() { return set_model_changed(true); } bool set_model_changed(bool changed) { bool old = model_changed_; @@ -57,13 +63,11 @@ class FontDataTable : virtual public RefCount { } protected: - explicit Builder(FontDataTableBuilderContainer* container); - Builder(FontDataTableBuilderContainer* container, WritableFontData* data); - Builder(FontDataTableBuilderContainer* container, ReadableFontData* data); + explicit Builder(); + Builder(WritableFontData* data); + Builder(ReadableFontData* data); virtual ~Builder(); - void Init(FontDataTableBuilderContainer* container); - // subclass API virtual void NotifyPostTableBuild(FontDataTable* table); virtual int32_t SubSerialize(WritableFontData* new_data) = 0; @@ -77,10 +81,10 @@ class FontDataTable : virtual public RefCount { void InternalSetData(WritableFontData* data, bool data_changed); void InternalSetData(ReadableFontData* data, bool data_changed); - FontDataTableBuilderContainer* container_; // avoid circular ref-counting WritableFontDataPtr w_data_; ReadableFontDataPtr r_data_; bool model_changed_; + bool contained_model_changed_; // may expand to list of submodel states bool data_changed_; }; @@ -91,21 +95,15 @@ class FontDataTable : virtual public RefCount { ReadableFontData* ReadFontData(); // Get the length of the data for this table in bytes. This is the full - // allocated length of the data and may or may not include any padding. - virtual int32_t Length(); - - // Get the number of bytes of padding used in the table. The padding bytes are - // used to align the table length to a 4 byte boundary. - virtual int32_t Padding(); - - // Return the number of bytes of non-padded data in the table. If the padding - // is unknown or unknowable then the total number of bytes of data in the - // tables is returned. + // allocated length of the data underlying the table and may or may not + // include any padding. virtual int32_t DataLength(); virtual int32_t Serialize(OutputStream* os); protected: + virtual int32_t Serialize(WritableFontData* data); + // TODO(arthurhsu): style guide violation: protected member, need refactoring ReadableFontDataPtr data_; }; diff --git a/sfntly/table/subtable.cc b/sfntly/table/subtable.cc index 4869a97..d70b18c 100644 --- a/sfntly/table/subtable.cc +++ b/sfntly/table/subtable.cc @@ -23,7 +23,7 @@ namespace sfntly { SubTable::~SubTable() {} SubTable::SubTable(ReadableFontData* data) - : FontDataTable(data) { + : FontDataTable(data), padding_(0) { } /****************************************************************************** @@ -31,14 +31,12 @@ SubTable::SubTable(ReadableFontData* data) ******************************************************************************/ SubTable::Builder::~Builder() {} -SubTable::Builder::Builder(FontDataTableBuilderContainer* container, - WritableFontData* data) - : FontDataTable::Builder(container, data) { +SubTable::Builder::Builder(WritableFontData* data) + : FontDataTable::Builder(data) { } -SubTable::Builder::Builder(FontDataTableBuilderContainer* container, - ReadableFontData* data) - : FontDataTable::Builder(container, data) { +SubTable::Builder::Builder(ReadableFontData* data) + : FontDataTable::Builder(data) { } } // namespace sfntly diff --git a/sfntly/table/subtable.h b/sfntly/table/subtable.h index c542881..e5ec748 100644 --- a/sfntly/table/subtable.h +++ b/sfntly/table/subtable.h @@ -32,16 +32,22 @@ class SubTable : public FontDataTable { virtual ~Builder(); protected: - Builder(FontDataTableBuilderContainer* container, WritableFontData* data); - Builder(FontDataTableBuilderContainer* container, ReadableFontData* data); + Builder(WritableFontData* data); + Builder(ReadableFontData* data); }; virtual ~SubTable(); + int32_t padding() { return padding_; } + void set_padding(int32_t padding) { padding_ = padding; } + protected: // Note: constructor refactored in C++ to avoid heavy lifting. // caller need to do data->Slice(offset, length) beforehand. explicit SubTable(ReadableFontData* data); + + private: + int32_t padding_; }; } // namespace sfntly diff --git a/sfntly/table/subtable_container_table.h b/sfntly/table/subtable_container_table.h new file mode 100644 index 0000000..e77ebbb --- /dev/null +++ b/sfntly/table/subtable_container_table.h @@ -0,0 +1,48 @@ +/* + * 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_TABLE_SUBTABLE_CONTAINER_TABLE_H_ +#define TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_ + +#include "sfntly/table/table.h" + +namespace sfntly { + +class SubTableContainerTable : public Table { + public: + class Builder : public Table::Builder { + public: + Builder(Header* header, WritableFontData* data) + : Table::Builder(header, data) { + } + + Builder(Header* header, ReadableFontData* data) + : Table::Builder(header, data) { + } + + virtual ~Builder() {} + }; + + SubTableContainerTable(Header* header, ReadableFontData* data) + : Table(header, data) { + } + + virtual ~SubTableContainerTable() {} +}; + +} // namespace sfntly + +#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
\ No newline at end of file diff --git a/sfntly/table/table.cc b/sfntly/table/table.cc index 568f889..10276aa 100644 --- a/sfntly/table/table.cc +++ b/sfntly/table/table.cc @@ -39,10 +39,6 @@ int64_t Table::CalculatedChecksum() { return data_->Checksum(); } -WritableFontData* Table::GetNewData(int32_t size) { - return font_->GetNewData(size); -} - void Table::SetFont(Font* font) { font_ = font; } @@ -58,8 +54,9 @@ Table::Table(Header* header, ReadableFontData* data) Table::Header::Header(int32_t tag) : tag_(tag), offset_(0), - length_(0), offset_valid_(false), + length_(0), + length_valid_(false), checksum_(0), checksum_valid_(false) { } @@ -67,8 +64,9 @@ Table::Header::Header(int32_t tag) Table::Header::Header(int32_t tag, int32_t length) : tag_(tag), offset_(0), - length_(length), offset_valid_(false), + length_(length), + length_valid_(true), checksum_(0), checksum_valid_(false) { } @@ -79,19 +77,25 @@ Table::Header::Header(int32_t tag, int32_t length) : tag_(tag), offset_(offset), - length_(length), offset_valid_(true), + length_(length), + length_valid_(true), checksum_(checksum), checksum_valid_(true) { } Table::Header::~Header() {} -bool TableHeaderComparator::operator() (const TableHeaderPtr lhs, - const TableHeaderPtr rhs) { +bool HeaderComparatorByOffset::operator() (const TableHeaderPtr lhs, + const TableHeaderPtr rhs) { return lhs->offset_ > rhs->offset_; } +bool HeaderComparatorByTag::operator() (const TableHeaderPtr lhs, + const TableHeaderPtr rhs) { + return lhs->tag_ > rhs->tag_; +} + /****************************************************************************** * Table::Builder class ******************************************************************************/ @@ -102,91 +106,77 @@ Table::Builder::~Builder() { void Table::Builder::NotifyPostTableBuild(FontDataTable* table) { if (model_changed() || data_changed()) { Table* derived_table = down_cast<Table*>(table); - header_ = new Header(header()->tag(), - derived_table->ReadFontData()->Length()); + derived_table->header_ = new Header(header()->tag(), + derived_table->DataLength()); } } -WritableFontData* Table::Builder::GetNewData(int32_t size) { - UNREFERENCED_PARAMETER(size); - return InternalWriteData(); -} - -CALLER_ATTACH Table::Builder* - Table::Builder::GetBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* table_data) { +CALLER_ATTACH +Table::Builder* Table::Builder::GetBuilder(Header* header, + WritableFontData* table_data) { int32_t tag = header->tag(); - TableBuilderPtr builder; Table::Builder* builder_raw = NULL; // Note: Tables are commented out when they are not used/ported. // TODO(arthurhsu): IMPLEMENT: finish tables that are not ported. /*if (tag == Tag::cmap) { builder_raw = static_cast<Table::Builder*>( - new CMapTable::Builder(font_builder, header, table_data)); + CMapTable::CreateBuilder(font_builder, header, table_data)); } else*/ if (tag == Tag::head) { builder_raw = static_cast<Table::Builder*>( - new FontHeaderTable::Builder(font_builder, header, table_data)); + FontHeaderTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::hhea) { builder_raw = static_cast<Table::Builder*>( - new HorizontalHeaderTable::Builder(font_builder, header, table_data)); + HorizontalHeaderTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::hmtx) { builder_raw = static_cast<Table::Builder*>( - new HorizontalMetricsTable::Builder(font_builder, header, table_data)); + HorizontalMetricsTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::maxp) { builder_raw = static_cast<Table::Builder*>( - new MaximumProfileTable::Builder(font_builder, header, table_data)); + MaximumProfileTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::name) { builder_raw = static_cast<Table::Builder*>( - new NameTable::Builder(font_builder, header, table_data)); + NameTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::OS_2) { builder_raw = static_cast<Table::Builder*>( - new OS2Table::Builder(font_builder, header, table_data)); + OS2Table::Builder::CreateBuilder(header, table_data)); }/* else if (tag == Tag::PostScript) { builder_raw = static_cast<Table::Builder*>( - new PostScriptTable::Builder(font_builder, header, table_data)); + PostScriptTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::cvt) { builder_raw = static_cast<Table::Builder*>( - new ControlValueTable::Builder(font_builder, header, table_data)); + ControlValueTable::Builder::CreateBuilder(header, table_data)); }*/ else if (tag == Tag::glyf) { builder_raw = static_cast<Table::Builder*>( - new GlyphTable::Builder(font_builder, header, table_data)); + GlyphTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::loca) { builder_raw = static_cast<Table::Builder*>( - new LocaTable::Builder(font_builder, header, table_data)); + LocaTable::Builder::CreateBuilder(header, table_data)); }/* else if (tag == Tag::prep) { builder_raw = static_cast<Table::Builder*>( - new ControlProgramTable::Builder(font_builder, header, table_data)); + ControlProgramTable::Builder::CreateBuilder(header, table_data)); }*/ else if (tag == Tag::bhed) { builder_raw = static_cast<Table::Builder*>( - new FontHeaderTable::Builder(font_builder, header, table_data)); + FontHeaderTable::Builder::CreateBuilder(header, table_data)); } else { builder_raw = static_cast<Table::Builder*>( - new Table::GenericTableBuilder(font_builder, header, table_data)); + Table::GenericTableBuilder::CreateBuilder(header, table_data)); } - builder = builder_raw; - return builder.Detach(); + return builder_raw; } -Table::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : FontDataTable::Builder(font_builder, data) { +Table::Builder::Builder(Header* header, WritableFontData* data) + : FontDataTable::Builder(data) { header_ = header; } -Table::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : FontDataTable::Builder(font_builder, data) { +Table::Builder::Builder(Header* header, ReadableFontData* data) + : FontDataTable::Builder(data) { header_ = header; } -Table::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header) - : FontDataTable::Builder(font_builder) { +Table::Builder::Builder(Header* header) { header_ = header; } @@ -212,24 +202,23 @@ void Table::TableBasedTableBuilder::SubDataSet() { table_ = NULL; } -Table::TableBasedTableBuilder::TableBasedTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Builder(font_builder, header, data) { +CALLER_ATTACH FontDataTable* Table::TableBasedTableBuilder::Build() { + FontDataTablePtr table = static_cast<FontDataTable*>(GetTable()); + return table.Detach(); +} + +Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header, + WritableFontData* data) + : Builder(header, data) { } -Table::TableBasedTableBuilder::TableBasedTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Builder(font_builder, header, data) { +Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header, + ReadableFontData* data) + : Builder(header, data) { } -Table::TableBasedTableBuilder::TableBasedTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header) - : Builder(font_builder, header) { +Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header) + : Builder(header) { } Table* Table::TableBasedTableBuilder::GetTable() { @@ -242,11 +231,9 @@ Table* Table::TableBasedTableBuilder::GetTable() { /****************************************************************************** * Table::GenericTableBuilder class ******************************************************************************/ -Table::GenericTableBuilder::GenericTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : TableBasedTableBuilder(font_builder, header, data) { +Table::GenericTableBuilder::GenericTableBuilder(Header* header, + WritableFontData* data) + : TableBasedTableBuilder(header, data) { } CALLER_ATTACH FontDataTable* @@ -257,23 +244,12 @@ CALLER_ATTACH FontDataTable* return table.Detach(); } -/****************************************************************************** - * Table::ArrayElementTableBuilder class - ******************************************************************************/ -Table::ArrayElementTableBuilder::~ArrayElementTableBuilder() {} - -Table::ArrayElementTableBuilder::ArrayElementTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Builder(font_builder, header, data) { -} - -Table::ArrayElementTableBuilder::ArrayElementTableBuilder( - FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data) - : Builder(font_builder, header, data) { +CALLER_ATTACH Table::GenericTableBuilder* + Table::GenericTableBuilder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<Table::GenericTableBuilder> builder = + new Table::GenericTableBuilder(header, data); + return builder.Detach(); } } // namespace sfntly diff --git a/sfntly/table/table.h b/sfntly/table/table.h index 8c8fcc8..5adbfb1 100644 --- a/sfntly/table/table.h +++ b/sfntly/table/table.h @@ -27,61 +27,91 @@ namespace sfntly { class Font; -class Table : public FontDataTable, public FontDataTableBuilderContainer { + +// A concrete implementation of a root level table in the font. This is the base +// class used for all specific table implementations and is used as the generic +// table for all tables which have no specific implementations. +class Table : public FontDataTable { public: class Header : public RefCounted<Header> { public: + // Make a partial header with only the basic info for an empty new table. explicit Header(int32_t tag); + + // Make a partial header with only the basic info for a new table. Header(int32_t tag, int32_t length); + + // Make a full header as read from an existing font. Header(int32_t tag, int64_t checksum, int32_t offset, int32_t length); virtual ~Header(); + // Get the table tag. int32_t tag() { return tag_; } + + // Get the table offset. The offset is from the start of the font file. int32_t offset() { return offset_; } - int32_t length() { return length_; } + + // Is the offset in the header valid. The offset will not be valid if the + // table was constructed during building and has no physical location in a + // font file. bool offset_valid() { return offset_valid_; } + + // Get the length of the table as recorded in the table record header. + int32_t length() { return length_; } + + // Is the length in the header valid. The length will not be valid if the + // table was constructed during building and has no physical location in a + // font file. + bool length_valid() { return length_valid_; } + + // Get the checksum for the table as recorded in the table record header. int64_t checksum() { return checksum_; } + + // Is the checksum valid. The checksum will not be valid if the table was + // constructed during building and has no physical location in a font file. + // Note that this does *NOT* check the validity of the checksum against + // the calculated checksum for the table data. bool checksum_valid() { return checksum_valid_; } + // UNIMPLEMENTED: boolean equals(Object obj) + // int hashCode() + // string toString() + private: int32_t tag_; int32_t offset_; - int32_t length_; bool offset_valid_; + int32_t length_; + bool length_valid_; int64_t checksum_; bool checksum_valid_; - friend class TableHeaderComparator; + friend class HeaderComparatorByOffset; + friend class HeaderComparatorByTag; }; // Note: original version is Builder<T extends Table> // C++ template is not designed that way so plain old inheritance is // chosen. - class Builder : public FontDataTable::Builder, - public FontDataTableBuilderContainer { + class Builder : public FontDataTable::Builder { public: virtual ~Builder(); virtual Header* header() { return header_; } virtual void NotifyPostTableBuild(FontDataTable* table); - virtual WritableFontData* GetNewData(int32_t size); - static CALLER_ATTACH Builder* - GetBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* table_data); + // Get a builder for the table type specified by the data in the header. + // @param header the header for the table + // @param tableData the data to be used to build the table from + // @return builder for the table specified + static CALLER_ATTACH Builder* GetBuilder(Header* header, + WritableFontData* table_data); + + // UNIMPLEMENTED: toString() protected: - // Note: original version is Font.Builder font_builder. This results in - // mutual inclusion happiness that Java solved for C++. Therefore, - // we need to avoid that happiness when we port it to C++. - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, - Header* header); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); + Builder(Header* header); private: Ptr<Header> header_; @@ -95,16 +125,12 @@ class Table : public FontDataTable, public FontDataTableBuilderContainer { virtual bool SubReadyToSerialize(); virtual int32_t SubDataSizeToSerialize(); virtual void SubDataSet(); + virtual CALLER_ATTACH FontDataTable* Build(); protected: - TableBasedTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - TableBasedTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); - TableBasedTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header); + TableBasedTableBuilder(Header* header, WritableFontData* data); + TableBasedTableBuilder(Header* header, ReadableFontData* data); + TableBasedTableBuilder(Header* header); // C++ port: renamed table() to GetTable() virtual Table* GetTable(); @@ -116,33 +142,36 @@ class Table : public FontDataTable, public FontDataTableBuilderContainer { class GenericTableBuilder : public TableBasedTableBuilder, public RefCounted<GenericTableBuilder> { public: - GenericTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); + GenericTableBuilder(Header* header, WritableFontData* data); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); - }; - - class ArrayElementTableBuilder : public Builder { - public: - virtual ~ArrayElementTableBuilder(); - protected: - ArrayElementTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); - ArrayElementTableBuilder(FontDataTableBuilderContainer* font_builder, - Header* header, - ReadableFontData* data); + static CALLER_ATTACH + GenericTableBuilder* CreateBuilder(Header* header, + WritableFontData* data); }; virtual ~Table(); + + // Get the calculated checksum for the data in the table. virtual int64_t CalculatedChecksum(); + + // Get the header for the table. virtual Header* header() { return header_; } + + // Get the tag for the table from the record header. virtual int32_t header_tag() { return header_->tag(); } + + // Get the offset for the table from the record header. virtual int32_t header_offset() { return header_->offset(); } + + // Get the length of the table from the record header. virtual int32_t header_length() { return header_->length(); } + + // Get the checksum for the table from the record header. virtual int64_t header_checksum() { return header_->checksum(); } - virtual WritableFontData* GetNewData(int32_t size); + + // UNIMPLEMENTED: toString() + virtual void SetFont(Font* font); protected: @@ -172,11 +201,31 @@ typedef std::pair<TableHeaderPtr, WritableFontDataPtr> DataBlockEntry; typedef std::map<int32_t, TableBuilderPtr> TableBuilderMap; typedef std::pair<int32_t, TableBuilderPtr> TableBuilderEntry; -class TableHeaderComparator { +class HeaderComparator { + public: + virtual ~HeaderComparator() {} + virtual bool operator()(const TableHeaderPtr h1, + const TableHeaderPtr h2) = 0; +}; + +class HeaderComparatorByOffset : public HeaderComparator { public: - bool operator()(const TableHeaderPtr h1, const TableHeaderPtr h2); + virtual ~HeaderComparatorByOffset() {} + virtual bool operator()(const TableHeaderPtr h1, + const TableHeaderPtr h2); }; -typedef std::set<TableHeaderPtr, TableHeaderComparator> TableHeaderSortedSet; + +class HeaderComparatorByTag : public HeaderComparator { + public: + virtual ~HeaderComparatorByTag() {} + virtual bool operator()(const TableHeaderPtr h1, + const TableHeaderPtr h2); +}; + +typedef std::set<TableHeaderPtr, HeaderComparatorByOffset> + HeaderOffsetSortedSet; +typedef std::set<TableHeaderPtr, HeaderComparatorByTag> + HeaderTagSortedSet; } // namespace sfntly diff --git a/sfntly/table/truetype/glyph_table.cc b/sfntly/table/truetype/glyph_table.cc index ff289f3..dc1163a 100644 --- a/sfntly/table/truetype/glyph_table.cc +++ b/sfntly/table/truetype/glyph_table.cc @@ -52,20 +52,18 @@ GlyphTable::~GlyphTable() { } GlyphTable::Glyph* GlyphTable::GetGlyph(int32_t offset, int32_t length) { - return GlyphTable::Glyph::GetGlyph(data_, offset, length); + return GlyphTable::Glyph::GetGlyph(this, this->data_, offset, length); } GlyphTable::GlyphTable(Header* header, ReadableFontData* data) - : Table(header, data) { + : SubTableContainerTable(header, data) { } /****************************************************************************** * GlyphTable::Builder class ******************************************************************************/ -GlyphTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data) - : Table::ArrayElementTableBuilder(font_builder, header, data) { +GlyphTable::Builder::Builder(Header* header, ReadableFontData* data) + : SubTableContainerTable::Builder(header, data) { } GlyphTable::Builder::~Builder() { @@ -96,6 +94,13 @@ void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) { } } +CALLER_ATTACH GlyphTable::Builder* + GlyphTable::Builder::CreateBuilder(Header* header, WritableFontData* data) { + Ptr<GlyphTable::Builder> builder; + builder = new GlyphTable::Builder(header, data); + return builder.Detach(); +} + GlyphTable::GlyphBuilderList* GlyphTable::Builder::GlyphBuilders() { return GetGlyphBuilders(); } @@ -157,12 +162,11 @@ void GlyphTable::Builder::Initialize(ReadableFontData* data, const IntegerList& loca) { if (data != NULL) { if (loca_.empty()) { -#if defined (SFNTLY_NO_EXCEPTION) - return; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IllegalStateException( "Loca values not set - unable to parse glyph data."); #endif + return; } int32_t loca_value; int32_t last_loca_value = loca[0]; @@ -199,9 +203,11 @@ void GlyphTable::Builder::Revert() { GlyphTable::Glyph::~Glyph() {} CALLER_ATTACH GlyphTable::Glyph* - GlyphTable::Glyph::GetGlyph(ReadableFontData* data, + GlyphTable::Glyph::GetGlyph(GlyphTable* table, + ReadableFontData* data, int32_t offset, int32_t length) { + UNREFERENCED_PARAMETER(table); int32_t type = GlyphType(data, offset, length); GlyphPtr glyph; @@ -239,10 +245,6 @@ int32_t GlyphTable::Glyph::YMax() { return data_->ReadShort(Offset::kYMax); } -int32_t GlyphTable::Glyph::Padding() { - return padding_; -} - GlyphTable::Glyph::Glyph(ReadableFontData* data, int32_t glyph_type) : SubTable(data), glyph_type_(glyph_type) { @@ -273,38 +275,36 @@ int32_t GlyphTable::Glyph::GlyphType(ReadableFontData* data, GlyphTable::Glyph::Builder::~Builder() { } -GlyphTable::Glyph::Builder::Builder(FontDataTableBuilderContainer* font_builder, - WritableFontData* data) - : SubTable::Builder(font_builder, data) { +GlyphTable::Glyph::Builder::Builder(WritableFontData* data) + : SubTable::Builder(data) { } -GlyphTable::Glyph::Builder::Builder(FontDataTableBuilderContainer* font_builder, - ReadableFontData* data) - : SubTable::Builder(font_builder, data) { +GlyphTable::Glyph::Builder::Builder(ReadableFontData* data) + : SubTable::Builder(data) { } CALLER_ATTACH GlyphTable::Glyph::Builder* GlyphTable::Glyph::Builder::GetBuilder( - FontDataTableBuilderContainer* table_builder, + GlyphTable::Builder* table_builder, ReadableFontData* data) { return GetBuilder(table_builder, data, 0, data->Length()); } CALLER_ATTACH GlyphTable::Glyph::Builder* GlyphTable::Glyph::Builder::GetBuilder( - FontDataTableBuilderContainer* table_builder, + GlyphTable::Builder* table_builder, ReadableFontData* data, int32_t offset, int32_t length) { + UNREFERENCED_PARAMETER(table_builder); int32_t type = Glyph::GlyphType(data, offset, length); GlyphBuilderPtr builder; ReadableFontDataPtr sliced_data; sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length))); if (type == GlyphType::kSimple) { - builder = new SimpleGlyph::SimpleGlyphBuilder(table_builder, sliced_data); + builder = new SimpleGlyph::SimpleGlyphBuilder(sliced_data); } else { - builder = new CompositeGlyph::CompositeGlyphBuilder(table_builder, - sliced_data); + builder = new CompositeGlyph::CompositeGlyphBuilder(sliced_data); } return builder.Detach(); } @@ -411,7 +411,7 @@ void GlyphTable::SimpleGlyph::Initialize() { (flag_byte_count_ * DataSize::kBYTE) + (x_byte_count_ * DataSize::kBYTE) + (y_byte_count_ * DataSize::kBYTE); - padding_ = Length() - non_padded_data_length; + set_padding(DataLength() - non_padded_data_length); initialized_ = true; } @@ -505,15 +505,13 @@ GlyphTable::SimpleGlyph::SimpleGlyphBuilder::~SimpleGlyphBuilder() { } GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder( - FontDataTableBuilderContainer* table_builder, WritableFontData* data) - : Glyph::Builder(table_builder, data) { + : Glyph::Builder(data) { } GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder( - FontDataTableBuilderContainer* table_builder, ReadableFontData* data) - : Glyph::Builder(table_builder, data) { + : Glyph::Builder(data) { } CALLER_ATTACH FontDataTable* @@ -635,7 +633,7 @@ void GlyphTable::CompositeGlyph::ParseData() { instructions_offset_ = index; non_padded_data_length = index + (instruction_size_ * DataSize::kBYTE); } - padding_ = Length() - non_padded_data_length; + set_padding(DataLength() - non_padded_data_length); } } @@ -646,15 +644,13 @@ GlyphTable::CompositeGlyph::CompositeGlyphBuilder::~CompositeGlyphBuilder() { } GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder( - FontDataTableBuilderContainer* table_builder, WritableFontData* data) - : Glyph::Builder(table_builder, data) { + : Glyph::Builder(data) { } GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder( - FontDataTableBuilderContainer* table_builder, ReadableFontData* data) - : Glyph::Builder(table_builder, data) { + : Glyph::Builder(data) { } CALLER_ATTACH FontDataTable* diff --git a/sfntly/table/truetype/glyph_table.h b/sfntly/table/truetype/glyph_table.h index 320c522..3ba9cac 100644 --- a/sfntly/table/truetype/glyph_table.h +++ b/sfntly/table/truetype/glyph_table.h @@ -21,6 +21,7 @@ #include "sfntly/table/table.h" #include "sfntly/table/subtable.h" +#include "sfntly/table/subtable_container_table.h" namespace sfntly { @@ -31,10 +32,8 @@ struct GlyphType { }; }; -// 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> { +class GlyphTable : public SubTableContainerTable, + public RefCounted<GlyphTable> { public: class Builder; class Glyph : public SubTable { @@ -54,16 +53,14 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { // 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); + Builder(WritableFontData* data); + Builder(ReadableFontData* data); static CALLER_ATTACH Builder* - GetBuilder(FontDataTableBuilderContainer* table_builder, + GetBuilder(GlyphTable::Builder* table_builder, ReadableFontData* data); static CALLER_ATTACH Builder* - GetBuilder(FontDataTableBuilderContainer* table_builder, + GetBuilder(GlyphTable::Builder* table_builder, ReadableFontData* data, int32_t offset, int32_t length); @@ -78,7 +75,8 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { }; virtual ~Glyph(); - static CALLER_ATTACH Glyph* GetGlyph(ReadableFontData* data, + static CALLER_ATTACH Glyph* GetGlyph(GlyphTable* table, + ReadableFontData* data, int32_t offset, int32_t length); virtual int32_t GlyphType(); @@ -87,7 +85,6 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { 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; @@ -97,9 +94,6 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { // 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, @@ -111,18 +105,19 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr; typedef std::vector<GlyphBuilderPtr> GlyphBuilderList; - class Builder : public Table::ArrayElementTableBuilder, + class Builder : public SubTableContainerTable::Builder, public RefCounted<GlyphTable::Builder> { public: // Note: Constructor scope altered to public for base class to instantiate. - Builder(FontDataTableBuilderContainer* font_builder, - Header* header, - WritableFontData* data); + 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. @@ -178,10 +173,8 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { 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); + SimpleGlyphBuilder(WritableFontData* data); + SimpleGlyphBuilder(ReadableFontData* data); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); @@ -251,10 +244,8 @@ class GlyphTable : public Table, public RefCounted<GlyphTable> { 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); + CompositeGlyphBuilder(WritableFontData* data); + CompositeGlyphBuilder(ReadableFontData* data); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); diff --git a/sfntly/table/truetype/loca_table.cc b/sfntly/table/truetype/loca_table.cc index 537e433..0a579ae 100644 --- a/sfntly/table/truetype/loca_table.cc +++ b/sfntly/table/truetype/loca_table.cc @@ -23,28 +23,22 @@ namespace sfntly { ******************************************************************************/ LocaTable::~LocaTable() {} -int32_t LocaTable::NumGlyphs() { - return num_glyphs_; -} - int32_t LocaTable::GlyphOffset(int32_t glyph_id) { if (glyph_id < 0 || glyph_id >= num_glyphs_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException("Glyph ID is out of bounds."); #endif + return 0; } return Loca(glyph_id); } int32_t LocaTable::GlyphLength(int32_t glyph_id) { if (glyph_id < 0 || glyph_id >= num_glyphs_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException("Glyph ID is out of bounds."); #endif + return 0; } return Loca(glyph_id + 1) - Loca(glyph_id); } @@ -55,27 +49,24 @@ int32_t LocaTable::NumLocas() { int32_t LocaTable::Loca(int32_t index) { if (index > num_glyphs_) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException(); #endif + return 0; } - if (version_ == IndexToLocFormat::kShortOffset) { + if (format_version_ == IndexToLocFormat::kShortOffset) { return 2 * data_->ReadUShort(index * DataSize::kUSHORT); } return data_->ReadULongAsInt(index * DataSize::kULONG); } -LocaTable::LocaTable(Header* header, ReadableFontData* data) - : Table(header, data) { -} - LocaTable::LocaTable(Header* header, ReadableFontData* data, - int32_t version, + int32_t format_version, int32_t num_glyphs) - : Table(header, data), version_(version), num_glyphs_(num_glyphs) { + : Table(header, data), + format_version_(format_version), + num_glyphs_(num_glyphs) { } /****************************************************************************** @@ -97,22 +88,26 @@ int32_t LocaTable::LocaIterator::Next() { /****************************************************************************** * LocaTable::Builder class ******************************************************************************/ -LocaTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, WritableFontData* data) : - Table::ArrayElementTableBuilder(font_builder, header, data) { - Init(); +LocaTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::Builder(header, data), + format_version_(IndexToLocFormat::kLongOffset), + num_glyphs_(-1) { } -LocaTable::Builder::Builder(FontDataTableBuilderContainer* font_builder, - Header* header, ReadableFontData* data) : - Table::ArrayElementTableBuilder(font_builder, header, data) { - Init(); +LocaTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::Builder(header, data), + format_version_(IndexToLocFormat::kLongOffset), + num_glyphs_(-1) { } LocaTable::Builder::~Builder() {} -void LocaTable::Builder::SetFormatVersion(int32_t format_version) { - format_version_ = format_version; +CALLER_ATTACH +LocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<LocaTable::Builder> builder; + builder = new LocaTable::Builder(header, data); + return builder.Detach(); } IntegerList* LocaTable::Builder::LocaList() { @@ -130,22 +125,20 @@ void LocaTable::Builder::SetLocaList(IntegerList* list) { int32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) { if (glyph_id < 0 || glyph_id > (num_glyphs_ + 1)) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException("Glyph ID is out of bounds."); #endif + return 0; } return Loca(glyph_id); } int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) { if (glyph_id < 0 || glyph_id > (num_glyphs_ + 1)) { -#if defined (SFNTLY_NO_EXCEPTION) - return 0; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IndexOutOfBoundException("Glyph ID is out of bounds."); #endif + return 0; } return Loca(glyph_id + 1) - Loca(glyph_id); } @@ -166,10 +159,6 @@ void LocaTable::Builder::Revert() { set_model_changed(false); } -void LocaTable::Builder::Clear() { - GetLocaList()->clear(); -} - int32_t LocaTable::Builder::NumLocas() { return GetLocaList()->size(); } @@ -178,8 +167,8 @@ int32_t LocaTable::Builder::Loca(int32_t index) { return GetLocaList()->at(index); } -CALLER_ATTACH FontDataTable* LocaTable::Builder::SubBuildTable( - ReadableFontData* data) { +CALLER_ATTACH +FontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) { FontDataTablePtr table = new LocaTable(header(), data, format_version_, num_glyphs_); return table.Detach(); @@ -216,19 +205,13 @@ int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) { return 0; } -void LocaTable::Builder::Init() { - num_glyphs_ = -1; - format_version_ = IndexToLocFormat::kLongOffset; -} - void LocaTable::Builder::Initialize(ReadableFontData* data) { if (data) { if (NumGlyphs() < 0) { -#if defined (SFNTLY_NO_EXCEPTION) - return; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw IllegalStateException("numglyphs not set on LocaTable Builder."); #endif + return; } LocaTablePtr table = new LocaTable(header(), data, format_version_, num_glyphs_); diff --git a/sfntly/table/truetype/loca_table.h b/sfntly/table/truetype/loca_table.h index ce7fa44..0ec13bd 100644 --- a/sfntly/table/truetype/loca_table.h +++ b/sfntly/table/truetype/loca_table.h @@ -22,6 +22,7 @@ namespace sfntly { +// A Loca table - 'loca'. class LocaTable : public Table, public RefCounted<LocaTable> { public: // Note: different implementation than Java, caller to instantiate this class @@ -37,24 +38,33 @@ class LocaTable : public Table, public RefCounted<LocaTable> { LocaTable* table_; // use dumb pointer since it's a composition object }; - class Builder : public Table::ArrayElementTableBuilder, - public RefCounted<Builder> { + class Builder : public Table::Builder, public RefCounted<Builder> { public: // Constructor scope altered to public for base class to instantiate. - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - WritableFontData* data); - Builder(FontDataTableBuilderContainer* font_builder, Header* header, - ReadableFontData* data); + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); virtual ~Builder(); - void SetFormatVersion(int32_t format_version); + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + + // Get the format version that will be used when the loca table is + // generated. + // @return the loca table format version + int32_t format_version() { return format_version_; } + void set_format_version(int32_t value) { format_version_ = value; } // Gets the List of locas for loca table builder. These may be manipulated // in any way by the caller and the changes will be reflected in the final - // loca table produced. + // loca table produced as long as no subsequent call is made to the + // SetLocaList(List) method. // If there is no current data for the loca table builder or the loca list // have not been previously set then this will return an empty List. IntegerList* LocaList(); + + // Set the list of locas to be used for building this table. If any existing + // list was already retrieved with the LocaList() method then the + // connection of that previous list to this builder will be broken. void SetLocaList(IntegerList* list); // Return the offset for the given glyph id. Valid glyph ids are from 0 to @@ -75,15 +85,25 @@ class LocaTable : public Table, public RefCounted<LocaTable> { // to be called (and <b>must</b> be) when the raw data for this builder has // been changed. void SetNumGlyphs(int32_t num_glyphs); + + // Get the number of glyphs that this builder has support for. int NumGlyphs(); + // Revert the loca table builder to the state contained in the last raw data + // set on the builder. That raw data may be that read from a font file when + // the font builder was created, that set by a user of the loca table + // builder, or null data if this builder was created as a new empty builder. void Revert(); - void Clear(); // Get the number of locations or locas. This will be one more than the // number of glyphs for this table since the last loca position is used to // indicate the size of the final glyph. int32_t NumLocas(); + + // Get the value from the loca table for the index specified. These are the + // raw values from the table that are used to compute the offset and size of + // a glyph in the glyph table. Valid index values run from 0 to the number + // of glyphs in the font. int32_t Loca(int32_t index); virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); @@ -93,8 +113,15 @@ class LocaTable : public Table, public RefCounted<LocaTable> { virtual int32_t SubSerialize(WritableFontData* new_data); private: - void Init(); // short hand for common code in ctors, C++ port only - void Initialize(ReadableFontData* data); // ported from Java + // Initialize the internal state from the data. Done lazily since in many + // cases the builder will be just creating a table object with no parsing + // required. + // @param data the data to initialize from + void Initialize(ReadableFontData* data); + + // Internal method to get the loca list if already generated and if not to + // initialize the state of the builder. + // @return the loca list IntegerList* GetLocaList(); int32_t format_version_; // Note: IndexToLocFormat @@ -103,7 +130,9 @@ class LocaTable : public Table, public RefCounted<LocaTable> { }; virtual ~LocaTable(); - int32_t NumGlyphs(); + + int32_t format_version() { return format_version_; } + int32_t num_glyphs() { return num_glyphs_; } // Return the offset for the given glyph id. Valid glyph ids are from 0 to the // one less than the number of glyphs. The zero entry is the special entry for @@ -127,13 +156,12 @@ class LocaTable : public Table, public RefCounted<LocaTable> { int32_t Loca(int32_t index); private: - LocaTable(Header* header, ReadableFontData* data); LocaTable(Header* header, ReadableFontData* data, - int32_t version, + int32_t format_version, int32_t num_glyphs); - int32_t version_; // Note: IndexToLocFormat + int32_t format_version_; // Note: Java's version, renamed to format_version_ int32_t num_glyphs_; friend class LocaIterator; diff --git a/sfntly/tools/subsetter/glyph_table_subsetter.cc b/sfntly/tools/subsetter/glyph_table_subsetter.cc index 644e137..b3d6b07 100644 --- a/sfntly/tools/subsetter/glyph_table_subsetter.cc +++ b/sfntly/tools/subsetter/glyph_table_subsetter.cc @@ -46,11 +46,10 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter, GlyphTablePtr glyph_table = down_cast<GlyphTable*>(font->GetTable(Tag::glyf)); LocaTablePtr loca_table = down_cast<LocaTable*>(font->GetTable(Tag::loca)); if (glyph_table == NULL || loca_table == NULL) { -#if defined (SFNTLY_NO_EXCEPTION) - return false; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw RuntimeException("Font to subset is not valid."); #endif + return false; } GlyphTableBuilderPtr glyph_table_builder = @@ -60,11 +59,10 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter, down_cast<LocaTable::Builder*> (font_builder->NewTableBuilder(Tag::loca)); if (glyph_table_builder == NULL || loca_table_builder == NULL) { -#if defined (SFNTLY_NO_EXCEPTION) - return false; -#else +#if !defined (SFNTLY_NO_EXCEPTION) throw RuntimeException("Builder for subset is not valid."); #endif + return false; } GlyphTable::GlyphBuilderList* glyph_builders = glyph_table_builder->GlyphBuilders(); @@ -77,7 +75,7 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter, glyph.Attach(glyph_table->GetGlyph(old_offset, old_length)); ReadableFontDataPtr data = glyph->ReadFontData(); WritableFontDataPtr copy_data; - copy_data.Attach(font_builder->GetNewData(data->Length())); + copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length())); data->CopyTo(copy_data); GlyphBuilderPtr glyph_builder; glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data)); diff --git a/sfntly/tools/subsetter/subsetter.cc b/sfntly/tools/subsetter/subsetter.cc index d1b64d9..7d98779 100644 --- a/sfntly/tools/subsetter/subsetter.cc +++ b/sfntly/tools/subsetter/subsetter.cc @@ -56,8 +56,8 @@ CALLER_ATTACH Font::Builder* Subsetter::Subset() { font_builder.Attach(font_factory_->NewFontBuilder()); IntegerSet table_tags; - for (TableMap::iterator i = font_->Tables()->begin(), - e = font_->Tables()->end(); i != e; ++i) { + for (TableMap::const_iterator i = font_->GetTableMap()->begin(), + e = font_->GetTableMap()->end(); i != e; ++i) { table_tags.insert(i->first); } if (!remove_tables_.empty()) { diff --git a/test/font_parsing_test.cc b/test/font_parsing_test.cc index 2e35c20..fb161a6 100644 --- a/test/font_parsing_test.cc +++ b/test/font_parsing_test.cc @@ -32,8 +32,6 @@ namespace sfntly { bool TestFontParsing() { ByteVector input_buffer; LoadFile(SAMPLE_TTF_FILE, &input_buffer); - ByteArrayPtr ba = new MemoryByteArray(&(input_buffer[0]), - input_buffer.size()); FontFactoryPtr factory; factory.Attach(FontFactory::GetInstance()); @@ -43,7 +41,7 @@ bool TestFontParsing() { FontBuilderPtr font_builder = font_builder_array[0]; // Memory based FontBuilderArray font_builder_array2; - factory->LoadFontsForBuilding(ba, &font_builder_array2); + factory->LoadFontsForBuilding(&input_buffer, &font_builder_array2); FontBuilderPtr font_builder2 = font_builder_array2[0]; for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) { @@ -121,9 +119,7 @@ bool TestTTFMemoryBasedReadWrite() { FontFactoryPtr factory; factory.Attach(FontFactory::GetInstance()); FontBuilderArray font_builder_array; - ByteArrayPtr ba = new MemoryByteArray(&(input_buffer[0]), - input_buffer.size()); - factory->LoadFontsForBuilding(ba, &font_builder_array); + factory->LoadFontsForBuilding(&input_buffer, &font_builder_array); FontBuilderPtr font_builder = font_builder_array[0]; FontPtr font; font.Attach(font_builder->Build()); diff --git a/test/memory_io_test.cc b/test/memory_io_test.cc new file mode 100755 index 0000000..b34e1e7 --- /dev/null +++ b/test/memory_io_test.cc @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#include <stdio.h> + +#include <algorithm> + +#include "gtest/gtest.h" +#include "sfntly/port/memory_input_stream.h" +#include "sfntly/port/memory_output_stream.h" +#include "sfntly/port/type.h" + +namespace { + const char* kTestData = +"01234567890123456789012345678901234567890123456789" // 50 +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx" // 100 +"yz"; // 102 + const size_t kTestBufferLen = 102; +} + +namespace sfntly { + +bool TestMemoryInputStream() { + ByteVector test_buffer; + test_buffer.resize(kTestBufferLen); + std::copy(kTestData, kTestData + kTestBufferLen, test_buffer.begin()); + + MemoryInputStream is; + is.Attach(&(test_buffer[0]), kTestBufferLen); + EXPECT_EQ(is.Available(), (int32_t)kTestBufferLen); + + // Read one byte + EXPECT_EQ(is.Read(), '0'); // position 1 + EXPECT_EQ(is.Read(), '1'); // position 2 + EXPECT_EQ(is.Read(), '2'); // position 3 + + // Read byte vector + ByteVector b; + b.resize(7); + EXPECT_EQ(is.Read(&b), 7); // position 10 + EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 3, 7), 0); + + b.resize(17); + EXPECT_EQ(is.Read(&b, 7, 10), 10); // position 20 + EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 3, 17), 0); + + // Test skip + b.clear(); + b.resize(10); + EXPECT_EQ(is.Skip(30), 30); // position 50 + EXPECT_EQ(is.Read(&b), 10); // position 60 + EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 50, 10), 0); + b.clear(); + b.resize(10); + EXPECT_EQ(is.Skip(-20), -20); // position 40 + EXPECT_EQ(is.Read(&b), 10); // position 50 + EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + 40, 10), 0); + + EXPECT_EQ(is.Available(), (int32_t)kTestBufferLen - 50); + EXPECT_EQ(is.Skip(-60), -50); // Out of bound, position 0 + EXPECT_EQ(is.Skip(kTestBufferLen + 10), (int32_t)kTestBufferLen); + + b.clear(); + b.resize(10); + is.Unread(&b); + EXPECT_EQ(memcmp(&(b[0]), &(test_buffer[0]) + kTestBufferLen - 10, 10), 0); + + return true; +} + +bool TestMemoryOutputStream() { + ByteVector test_buffer; + test_buffer.resize(kTestBufferLen); + std::copy(kTestData, kTestData + kTestBufferLen, test_buffer.begin()); + + MemoryOutputStream os; + os.Write(&(test_buffer[0]), (int32_t)50, (int32_t)(kTestBufferLen - 50)); + EXPECT_EQ(os.Size(), kTestBufferLen - 50); + EXPECT_EQ(memcmp(os.Get(), &(test_buffer[0]) + 50, kTestBufferLen - 50), 0); + + return true; +} + +} // namespace sfntly + +TEST(MemoryIO, All) { + ASSERT_TRUE(sfntly::TestMemoryInputStream()); + ASSERT_TRUE(sfntly::TestMemoryOutputStream()); +} diff --git a/test/name_editing_test.cc b/test/name_editing_test.cc index ce12cd3..260d9d4 100644 --- a/test/name_editing_test.cc +++ b/test/name_editing_test.cc @@ -24,9 +24,10 @@ #include "sfntly/data/memory_byte_array.h" #include "sfntly/font.h" #include "sfntly/font_factory.h" +#include "sfntly/port/memory_input_stream.h" +#include "sfntly/port/memory_output_stream.h" #include "sfntly/table/core/name_table.h" #include "sfntly/tag.h" -#include "sfntly/port/memory_output_stream.h" #include "test/test_data.h" #include "test/test_font_utils.h" @@ -40,11 +41,7 @@ void LoadTestFile(FontFactory* factory, FontBuilderArray* font_builders) { if (input_buffer.empty()) { LoadFile(SAMPLE_TTF_FILE, &input_buffer); } - - ByteArrayPtr ba = - new MemoryByteArray(&(input_buffer[0]), input_buffer.size()); - - factory->LoadFontsForBuilding(ba, font_builders); + factory->LoadFontsForBuilding(&input_buffer, font_builders); } bool TestChangeOneName() { @@ -73,9 +70,10 @@ bool TestChangeOneName() { // Serialize and reload the serialized font. MemoryOutputStream os; factory->SerializeFont(font, &os); + MemoryInputStream is; + is.Attach(os.Get(), os.Size()); FontArray font_array; - ByteArrayPtr new_ba = new MemoryByteArray(os.Get(), os.Size()); - factory->LoadFonts(new_ba, &font_array); + factory->LoadFonts(&is, &font_array); FontPtr new_font = font_array[0]; // Check the font name. @@ -121,9 +119,10 @@ bool TestModifyNameTableAndRevert() { // Serialize and reload the serialized font. MemoryOutputStream os; factory->SerializeFont(font, &os); + MemoryInputStream is; + is.Attach(os.Get(), os.Size()); FontArray font_array; - ByteArrayPtr new_ba = new MemoryByteArray(os.Get(), os.Size()); - factory->LoadFonts(new_ba, &font_array); + factory->LoadFonts(&is, &font_array); FontPtr new_font = font_array[0]; // Check the font name. @@ -166,9 +165,10 @@ bool TestRemoveOneName() { // Serialize and reload the serialized font. MemoryOutputStream os; factory->SerializeFont(font, &os); + MemoryInputStream is; + is.Attach(os.Get(), os.Size()); FontArray font_array; - ByteArrayPtr new_ba = new MemoryByteArray(os.Get(), os.Size()); - factory->LoadFonts(new_ba, &font_array); + factory->LoadFonts(&is, &font_array); FontPtr new_font = font_array[0]; // Check the font name. diff --git a/test/otf_basic_editing_test.cc b/test/otf_basic_editing_test.cc index 32ba248..c99a3a3 100644 --- a/test/otf_basic_editing_test.cc +++ b/test/otf_basic_editing_test.cc @@ -39,6 +39,7 @@ bool TestOTFBasicEditing() { EXPECT_TRUE(font_builder != NULL); TableBuilderMap* builder_map = font_builder->table_builders(); EXPECT_TRUE(builder_map != NULL); + IntegerSet builder_tags; for (TableBuilderMap::iterator i = builder_map->begin(), e = builder_map->end(); i != e; ++i) { EXPECT_TRUE(i->second != NULL); @@ -47,11 +48,11 @@ bool TestOTFBasicEditing() { int32_t value = ToBE32(i->first); memcpy(tag, &value, 4); fprintf(stderr, "tag %s does not have valid builder\n", tag); + } else { + builder_tags.insert(i->first); } } - IntegerSet builder_tags; - font_builder->TableBuilderTags(&builder_tags); FontHeaderTableBuilderPtr header_builder = down_cast<FontHeaderTable::Builder*>( font_builder->GetTableBuilder(Tag::head)); @@ -61,9 +62,9 @@ bool TestOTFBasicEditing() { font.Attach(font_builder->Build()); // ensure every table had a builder - TableMap* table_map = font->Tables(); - for (TableMap::iterator i = table_map->begin(), e = table_map->end(); - i != e; ++i) { + const TableMap* table_map = font->GetTableMap(); + for (TableMap::const_iterator i = table_map->begin(), e = table_map->end(); + i != e; ++i) { TablePtr table = (*i).second; TableHeaderPtr header = table->header(); EXPECT_TRUE(builder_tags.find(header->tag()) != builder_tags.end()); diff --git a/test/serialization_test.cc b/test/serialization_test.cc index 08c8288..3df6d95 100755 --- a/test/serialization_test.cc +++ b/test/serialization_test.cc @@ -17,7 +17,8 @@ #include "gtest/gtest.h" #include "sfntly/font.h" #include "sfntly/font_factory.h" -#include "sfntly/data/memory_byte_array.h" +#include "sfntly/port/memory_input_stream.h" +#include "sfntly/port/memory_output_stream.h" #include "test/test_data.h" #include "test/test_font_utils.h" #include "test/serialization_test.h" @@ -43,20 +44,21 @@ bool TestSerialization() { factory3.Attach(FontFactory::GetInstance()); FontArray new_font_array; - ByteArrayPtr ba = new MemoryByteArray(os.Get(), os.Size()); - factory3->LoadFonts(ba, &new_font_array); + MemoryInputStream is; + is.Attach(os.Get(), os.Size()); + factory3->LoadFonts(&is, &new_font_array); FontPtr serialized = new_font_array[0]; // Check number of tables EXPECT_EQ(original->num_tables(), serialized->num_tables()); // Check if same set of tables - TableMap* original_tables = original->Tables(); - TableMap* serialized_tables = serialized->Tables(); + const TableMap* original_tables = original->GetTableMap(); + const TableMap* serialized_tables = serialized->GetTableMap(); EXPECT_EQ(original_tables->size(), serialized_tables->size()); - TableMap::iterator not_found = serialized_tables->end(); - for (TableMap::iterator b = original_tables->begin(), - e = original_tables->end(); b != e; ++b) { + TableMap::const_iterator not_found = serialized_tables->end(); + for (TableMap::const_iterator b = original_tables->begin(), + e = original_tables->end(); b != e; ++b) { EXPECT_TRUE((serialized_tables->find(b->first) != not_found)); } @@ -67,7 +69,7 @@ bool TestSerialization() { TablePtr serialized_table = serialized->GetTable(TTF_KNOWN_TAGS[i]); EXPECT_EQ(original_table->CalculatedChecksum(), serialized_table->CalculatedChecksum()); - EXPECT_EQ(original_table->Length(), serialized_table->Length()); + EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength()); if (TTF_KNOWN_TAGS[i] == Tag::hhea) { EXPECT_TRUE(VerifyHHEA(original_table, serialized_table)); diff --git a/test/subsetter_impl.cc b/test/subsetter_impl.cc index 572f00e..f82a674 100644 --- a/test/subsetter_impl.cc +++ b/test/subsetter_impl.cc @@ -28,6 +28,7 @@ #include "sfntly/table/truetype/loca_table.h" #include "sfntly/tag.h" #include "sfntly/data/memory_byte_array.h" +#include "sfntly/port/memory_input_stream.h" #include "sfntly/port/memory_output_stream.h" namespace sfntly { @@ -81,14 +82,14 @@ SubsetterImpl::~SubsetterImpl() { bool SubsetterImpl::LoadFont(const char* font_name, const unsigned char* original_font, size_t font_size) { - ByteArrayPtr raw_font = - new MemoryByteArray((byte_t*)original_font, font_size); + MemoryInputStream mis; + mis.Attach(original_font, font_size); if (factory_ == NULL) { factory_.Attach(FontFactory::GetInstance()); } FontArray font_array; - factory_->LoadFonts(raw_font, &font_array); + factory_->LoadFonts(&mis, &font_array); font_ = FindFont(font_name, font_array); if (font_ == NULL) { return false; @@ -223,7 +224,7 @@ bool SubsetterImpl::ResolveCompositeGlyphs(const unsigned int* glyph_ids, IntegerSet comp_glyph_id; for (IntegerSet::iterator i = glyph_id_remaining.begin(), e = glyph_id_remaining.end(); i != e; ++i) { - if (*i < 0 || *i >= loca_table->NumGlyphs()) { + if (*i < 0 || *i >= loca_table->num_glyphs()) { // Invalid glyph id, ignore. continue; } @@ -285,7 +286,7 @@ CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) { // Extract glyphs and setup loca list. IntegerList loca_list; - loca_list.resize(loca_table->NumGlyphs()); + loca_list.resize(loca_table->num_glyphs()); loca_list.push_back(0); int32_t last_glyph_id = 0; int32_t last_offset = 0; @@ -302,7 +303,7 @@ CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) { // Add glyph to new glyf table. ReadableFontDataPtr data = glyph->ReadFontData(); WritableFontDataPtr copy_data; - copy_data.Attach(font_builder->GetNewData(data->Length())); + copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length())); data->CopyTo(copy_data); GlyphBuilderPtr glyph_builder; glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data)); @@ -316,14 +317,14 @@ CALLER_ATTACH Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids) { loca_list[*i + 1] = last_offset; last_glyph_id = *i; } - for (int32_t j = last_glyph_id + 1; j <= loca_table->NumGlyphs(); ++j) { + for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) { loca_list[j] = last_offset; } loca_table_builder->SetLocaList(&loca_list); // Setup remaining builders. - for (TableMap::iterator i = font_->Tables()->begin(), - e = font_->Tables()->end(); i != e; ++i) { + for (TableMap::const_iterator i = font_->GetTableMap()->begin(), + e = font_->GetTableMap()->end(); i != e; ++i) { // We already build the builder for glyph and loca. if (i->first != Tag::glyf && i->first != Tag::loca) { font_builder->NewTableBuilder(i->first, i->second->ReadFontData()); diff --git a/test/test_font_utils.cc b/test/test_font_utils.cc index 99b65fe..d59b52b 100644 --- a/test/test_font_utils.cc +++ b/test/test_font_utils.cc @@ -49,17 +49,15 @@ void LoadFont(const char* font_path, FontFactory* factory, FontArray* fonts) { is.Close(); } -void LoadFontUsingByteArray(const char* font_path, +void LoadFontUsingByteVector(const char* font_path, bool fingerprint, FontArray* fonts) { - ByteArrayPtr b = new GrowableMemoryByteArray; ByteVector bv; LoadFile(font_path, &bv); - b->Put(0, &bv); FontFactoryPtr factory; factory.Attach(FontFactory::GetInstance()); factory->FingerprintFont(fingerprint); - factory->LoadFonts(b, fonts); + factory->LoadFonts(&bv, fonts); } void LoadFile(const char* input_file_path, ByteVector* input_buffer) { diff --git a/test/test_font_utils.h b/test/test_font_utils.h index b8a93b9..57fde7a 100644 --- a/test/test_font_utils.h +++ b/test/test_font_utils.h @@ -27,7 +27,7 @@ void BuilderForFontFile(const char* font_path, FontFactory* factory, FontBuilderArray* builders); void SerializeFont(const char* font_path, FontFactory* factory, Font* font); void LoadFont(const char* font_path, FontFactory* factory, FontArray* fonts); -void LoadFontUsingByteArray(const char* font_path, +void LoadFontUsingByteVector(const char* font_path, bool fingerprint, FontArray* fonts); diff --git a/test/verify_hhea.cc b/test/verify_hhea.cc index 491238a..05886d4 100644 --- a/test/verify_hhea.cc +++ b/test/verify_hhea.cc @@ -37,7 +37,7 @@ static bool VerifyHHEA(Table* table) { return false; } - EXPECT_EQ(hhea->Version(), SFNTVERSION_1); + EXPECT_EQ(hhea->TableVersion(), SFNTVERSION_1); EXPECT_EQ(hhea->Ascender(), HHEA_ASCENDER); EXPECT_EQ(hhea->Descender(), HHEA_DESCENDER); EXPECT_EQ(hhea->AdvanceWidthMax(), HHEA_ADVANCE_WIDTH_MAX); diff --git a/test/verify_loca.cc b/test/verify_loca.cc index 0e36ce8..3090841 100644 --- a/test/verify_loca.cc +++ b/test/verify_loca.cc @@ -230,7 +230,7 @@ static bool VerifyLOCA(Table* table) { } EXPECT_EQ(loca->NumLocas(), LOCA_NUM_LOCAS); - EXPECT_EQ(loca->NumGlyphs(), LOCA_NUM_LOCAS - 1); + EXPECT_EQ(loca->num_glyphs(), LOCA_NUM_LOCAS - 1); for (int32_t i = 0; i < LOCA_NUM_LOCAS - 1; ++i) { EXPECT_EQ(loca->GlyphOffset(i), LOCAS[i]); diff --git a/test/verify_maxp.cc b/test/verify_maxp.cc index 3bd4490..3b8e183 100644 --- a/test/verify_maxp.cc +++ b/test/verify_maxp.cc @@ -42,13 +42,12 @@ static bool VerifyMAXP(Table* table) { return false; } - EXPECT_EQ(maxp->Version(), SFNTVERSION_1); + EXPECT_EQ(maxp->TableVersion(), SFNTVERSION_1); EXPECT_EQ(maxp->NumGlyphs(), MAXP_NUM_GLYPHS); EXPECT_EQ(maxp->MaxPoints(), MAXP_MAX_POINTS); EXPECT_EQ(maxp->MaxContours(), MAXP_MAX_CONTOURS); EXPECT_EQ(maxp->MaxCompositePoints(), MAXP_MAX_COMPOSITE_POINTS); - // TODO(arthurhsu): maxCompositeContours observed in Microsoft TTF report. - // Check with stuartg and see if this is a miss. + EXPECT_EQ(maxp->MaxCompositeContours(), MAXP_MAX_COMPOSITE_CONTOURS); EXPECT_EQ(maxp->MaxZones(), MAXP_MAX_ZONES); EXPECT_EQ(maxp->MaxTwilightPoints(), MAXP_MAX_TWILIGHT_POINTS); EXPECT_EQ(maxp->MaxStorage(), MAXP_MAX_STORAGE); diff --git a/test/verify_os2.cc b/test/verify_os2.cc index 8f6b9ed..4713e44 100644 --- a/test/verify_os2.cc +++ b/test/verify_os2.cc @@ -60,7 +60,7 @@ static bool VerifyOS_2(Table* table) { return false; } - EXPECT_EQ(os2->Version(), OS2_VERSION); + EXPECT_EQ(os2->TableVersion(), OS2_VERSION); EXPECT_EQ(os2->XAvgCharWidth(), OS2_XAVG_CHAR_WIDTH); EXPECT_EQ(os2->UsWeightClass(), OS2_US_WEIGHT_CLASS); EXPECT_EQ(os2->UsWidthClass(), OS2_US_WIDTH_CLASS); @@ -107,7 +107,6 @@ static bool VerifyOS_2(Table* table) { EXPECT_EQ(os2->UlCodePageRange1(), OS2_UL_CODE_PAGE_RANGE1); EXPECT_EQ(os2->UlCodePageRange2(), OS2_UL_CODE_PAGE_RANGE2); - // TODO(arthurhsu): UlCodePageRange() not tested // TODO(arthurhsu): SxHeight() not tested // TODO(arthurhsu): SCapHeight() not tested // TODO(arthurhsu): UsDefaultChar() not tested |