diff options
author | Colin Cross <ccross@android.com> | 2017-04-07 10:50:33 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2017-04-07 11:01:22 -0700 |
commit | d7c3ad1d95c38b33c49a462f2647dc10f1fff7b7 (patch) | |
tree | a77368b5efd882b6d7c224d8fd9f5b6948d48071 /cpp/src/sfntly/font.cc | |
parent | d4aea7c865084a140a965d4c413c6c38f9a2743a (diff) | |
parent | 64f78562d2003eb7cacaaa86a398cbd41881ba6f (diff) | |
download | sfntly-d7c3ad1d95c38b33c49a462f2647dc10f1fff7b7.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into master
Bug: 32096780
Test: mmma -j external/skia
Change-Id: Ia60d7b9984c1007e82bfea10c1a6df32418100d5
(cherry picked from commit bd503d67f403ca1e1d33226626c494d5513701e4)
Diffstat (limited to 'cpp/src/sfntly/font.cc')
-rw-r--r-- | cpp/src/sfntly/font.cc | 113 |
1 files changed, 64 insertions, 49 deletions
diff --git a/cpp/src/sfntly/font.cc b/cpp/src/sfntly/font.cc index 347e0c1..ca35048 100644 --- a/cpp/src/sfntly/font.cc +++ b/cpp/src/sfntly/font.cc @@ -40,24 +40,27 @@ namespace sfntly { -const int32_t SFNTVERSION_MAJOR = 1; -const int32_t SFNTVERSION_MINOR = 0; +namespace { + +const int32_t kSFNTVersionMajor = 1; +const int32_t kSFNTVersionMinor = 0; + +const int32_t kMaxTableSize = 200 * 1024 * 1024; + +} // namespace /****************************************************************************** * Font class ******************************************************************************/ Font::~Font() {} -bool Font::HasTable(int32_t tag) { - TableMap::const_iterator result = tables_.find(tag); - TableMap::const_iterator end = tables_.end(); - return (result != end); +bool Font::HasTable(int32_t tag) const { + return tables_.find(tag) != tables_.end(); } Table* Font::GetTable(int32_t tag) { - if (!HasTable(tag)) { + if (!HasTable(tag)) return NULL; - } return tables_[tag]; } @@ -308,15 +311,12 @@ Table::Builder* Font::Builder::NewTableBuilder(int32_t tag, } void Font::Builder::RemoveTableBuilder(int32_t tag) { - TableBuilderMap::iterator target = table_builders_.find(tag); - if (target != table_builders_.end()) { - table_builders_.erase(target); - } + table_builders_.erase(tag); } Font::Builder::Builder(FontFactory* factory) : factory_(factory), - sfnt_version_(Fixed1616::Fixed(SFNTVERSION_MAJOR, SFNTVERSION_MINOR)) { + sfnt_version_(Fixed1616::Fixed(kSFNTVersionMajor, kSFNTVersionMinor)) { } void Font::Builder::LoadFont(InputStream* is) { @@ -393,57 +393,66 @@ void Font::Builder::BuildTablesFromBuilders(Font* font, } static Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) { - if (builder_map) { - TableBuilderMap::iterator target = builder_map->find(tag); - if (target != builder_map->end()) { - return target->second.p_; - } - } + if (!builder_map) + return NULL; - return NULL; + TableBuilderMap::iterator target = builder_map->find(tag); + if (target == builder_map->end()) + return NULL; + + return target->second.p_; +} + +// Like GetBuilder(), but the returned Builder must be able to support reads. +static Table::Builder* GetReadBuilder(TableBuilderMap* builder_map, int32_t tag) { + Table::Builder* builder = GetBuilder(builder_map, tag); + if (!builder || !builder->InternalReadData()) + return NULL; + + return builder; } void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { - Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head); + Table::Builder* raw_head_builder = GetReadBuilder(builder_map, Tag::head); FontHeaderTableBuilderPtr header_table_builder; if (raw_head_builder != NULL) { - header_table_builder = - down_cast<FontHeaderTable::Builder*>(raw_head_builder); + header_table_builder = + down_cast<FontHeaderTable::Builder*>(raw_head_builder); } - Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea); + Table::Builder* raw_hhea_builder = GetReadBuilder(builder_map, Tag::hhea); HorizontalHeaderTableBuilderPtr horizontal_header_builder; if (raw_head_builder != NULL) { - horizontal_header_builder = - down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder); + horizontal_header_builder = + down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder); } - Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp); + Table::Builder* raw_maxp_builder = GetReadBuilder(builder_map, Tag::maxp); MaximumProfileTableBuilderPtr max_profile_builder; if (raw_maxp_builder != NULL) { - max_profile_builder = - down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder); + max_profile_builder = + down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder); } Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca); LocaTableBuilderPtr loca_table_builder; if (raw_loca_builder != NULL) { - loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder); + loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder); } Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx); HorizontalMetricsTableBuilderPtr horizontal_metrics_builder; if (raw_hmtx_builder != NULL) { - horizontal_metrics_builder = - down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder); + horizontal_metrics_builder = + down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder); } #if defined (SFNTLY_EXPERIMENTAL) Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx); HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder; if (raw_hdmx_builder != NULL) { - hdmx_table_builder = - down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder); + hdmx_table_builder = + down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder); } #endif @@ -525,32 +534,38 @@ void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, FontInputStream* is, DataBlockMap* table_data) { assert(table_data); - for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), + for (HeaderOffsetSortedSet::iterator it = 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()); + it != table_end; + ++it) { + const Ptr<Header> header = *it; + is->Skip(header->offset() - is->position()); + if (header->length() > kMaxTableSize) + continue; + + FontInputStream table_is(is, header->length()); WritableFontDataPtr data; - data.Attach( - WritableFontData::CreateWritableFontData((*table_header)->length())); - data->CopyFrom(&table_is, (*table_header)->length()); - table_data->insert(DataBlockEntry(*table_header, data)); + data.Attach(WritableFontData::CreateWritableFontData(header->length())); + data->CopyFrom(&table_is, header->length()); + table_data->insert(DataBlockEntry(header, data)); } } void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers, WritableFontData* fd, DataBlockMap* table_data) { - for (HeaderOffsetSortedSet::iterator table_header = headers->begin(), + for (HeaderOffsetSortedSet::iterator it = headers->begin(), table_end = headers->end(); - table_header != table_end; - ++table_header) { + it != table_end; + ++it) { + const Ptr<Header> header = *it; + if (header->length() > kMaxTableSize) + continue; + FontDataPtr sliced_data; - sliced_data.Attach( - fd->Slice((*table_header)->offset(), (*table_header)->length())); + sliced_data.Attach(fd->Slice(header->offset(), header->length())); WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_); - table_data->insert(DataBlockEntry(*table_header, data)); + table_data->insert(DataBlockEntry(header, data)); } } |