summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51>2011-09-01 18:23:15 +0000
committerarthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51>2011-09-01 18:23:15 +0000
commitb54cce09c1fc2b09e2adae43d7eb017b47b0cccf (patch)
tree4cf24ed13da6135e9471882fc17699d8eaac73a0
parent6c4f92bcc799598f6fcba4b3c7d4d549da9a8491 (diff)
downloadsrc-b54cce09c1fc2b09e2adae43d7eb017b47b0cccf.tar.gz
Advance C++ port to Aug 11 Java snapshot
git-svn-id: http://sfntly.googlecode.com/svn/trunk/cpp/src@70 672e30a5-4c29-85ac-ac6d-611c735e0a51
-rw-r--r--sample/subsetter/subset_util.cc3
-rw-r--r--sfntly/font.cc176
-rw-r--r--sfntly/font.h136
-rw-r--r--sfntly/font_data_table_builder_container.h34
-rw-r--r--sfntly/font_factory.cc119
-rw-r--r--sfntly/font_factory.h24
-rw-r--r--sfntly/port/config.h4
-rw-r--r--sfntly/port/file_input_stream.cc34
-rwxr-xr-xsfntly/port/memory_input_stream.cc147
-rwxr-xr-xsfntly/port/memory_input_stream.h57
-rw-r--r--sfntly/table/core/cmap_table.cc118
-rw-r--r--sfntly/table/core/cmap_table.h47
-rw-r--r--sfntly/table/core/font_header_table.cc18
-rw-r--r--sfntly/table/core/font_header_table.h9
-rw-r--r--sfntly/table/core/horizontal_header_table.cc28
-rw-r--r--sfntly/table/core/horizontal_header_table.h19
-rw-r--r--sfntly/table/core/horizontal_metrics_table.cc53
-rw-r--r--sfntly/table/core/horizontal_metrics_table.h16
-rw-r--r--sfntly/table/core/maximum_profile_table.cc42
-rw-r--r--sfntly/table/core/maximum_profile_table.h19
-rw-r--r--sfntly/table/core/name_table.cc28
-rw-r--r--sfntly/table/core/name_table.h49
-rw-r--r--sfntly/table/core/os2_table.cc350
-rw-r--r--sfntly/table/core/os2_table.h109
-rw-r--r--sfntly/table/font_data_table.cc53
-rw-r--r--sfntly/table/font_data_table.h36
-rw-r--r--sfntly/table/subtable.cc12
-rw-r--r--sfntly/table/subtable.h10
-rw-r--r--sfntly/table/subtable_container_table.h48
-rw-r--r--sfntly/table/table.cc144
-rw-r--r--sfntly/table/table.h147
-rw-r--r--sfntly/table/truetype/glyph_table.cc66
-rw-r--r--sfntly/table/truetype/glyph_table.h45
-rw-r--r--sfntly/table/truetype/loca_table.cc83
-rw-r--r--sfntly/table/truetype/loca_table.h58
-rw-r--r--sfntly/tools/subsetter/glyph_table_subsetter.cc12
-rw-r--r--sfntly/tools/subsetter/subsetter.cc4
-rw-r--r--test/font_parsing_test.cc8
-rwxr-xr-xtest/memory_io_test.cc102
-rw-r--r--test/name_editing_test.cc24
-rw-r--r--test/otf_basic_editing_test.cc11
-rwxr-xr-xtest/serialization_test.cc20
-rw-r--r--test/subsetter_impl.cc19
-rw-r--r--test/test_font_utils.cc6
-rw-r--r--test/test_font_utils.h2
-rw-r--r--test/verify_hhea.cc2
-rw-r--r--test/verify_loca.cc2
-rw-r--r--test/verify_maxp.cc5
-rw-r--r--test/verify_os2.cc3
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