diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-11-28 11:56:15 +0000 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-11-28 11:56:15 +0000 |
commit | 58f132533b4126b00bc71fd9aed69ecf568cdf39 (patch) | |
tree | 3409a319b231317c63b0b3477c161c76822bcb92 /sfntly/table/truetype/loca_table.cc | |
parent | 0232d0f400400568410e1f85e7aba28bcd2ac183 (diff) | |
parent | 4a8c3597eb72a7042ead9632e4c3e4fddb5ac695 (diff) | |
download | src-58f132533b4126b00bc71fd9aed69ecf568cdf39.tar.gz |
Merge from Chromium at DEPS revision 237746android-4.4w_r1android-4.4.4_r2.0.1android-4.4.4_r2android-4.4.4_r1.0.1android-4.4.4_r1android-4.4.3_r1.1.0.1android-4.4.3_r1.1android-4.4.3_r1.0.1android-4.4.3_r1kitkat-wearkitkat-mr2.2-releasekitkat-mr2.1-releasekitkat-mr2-releasekitkat-devidea133-weekly-release
This commit was generated by merge_to_master.py.
Change-Id: If4ff821474cc985d0bc16bc22c8180c8bec48014
Diffstat (limited to 'sfntly/table/truetype/loca_table.cc')
-rw-r--r-- | sfntly/table/truetype/loca_table.cc | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/sfntly/table/truetype/loca_table.cc b/sfntly/table/truetype/loca_table.cc new file mode 100644 index 0000000..c692155 --- /dev/null +++ b/sfntly/table/truetype/loca_table.cc @@ -0,0 +1,246 @@ +/* + * 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 "sfntly/table/truetype/loca_table.h" +#include "sfntly/port/exception_type.h" + +namespace sfntly { +/****************************************************************************** + * LocaTable class + ******************************************************************************/ +LocaTable::~LocaTable() {} + +int32_t LocaTable::GlyphOffset(int32_t glyph_id) { + if (glyph_id < 0 || glyph_id >= num_glyphs_) { +#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) + throw IndexOutOfBoundException("Glyph ID is out of bounds."); +#endif + return 0; + } + return Loca(glyph_id + 1) - Loca(glyph_id); +} + +int32_t LocaTable::NumLocas() { + return num_glyphs_ + 1; +} + +int32_t LocaTable::Loca(int32_t index) { + if (index > num_glyphs_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundException(); +#endif + return 0; + } + if (format_version_ == IndexToLocFormat::kShortOffset) { + return 2 * data_->ReadUShort(index * DataSize::kUSHORT); + } + return data_->ReadULongAsInt(index * DataSize::kULONG); +} + +LocaTable::LocaTable(Header* header, + ReadableFontData* data, + int32_t format_version, + int32_t num_glyphs) + : Table(header, data), + format_version_(format_version), + num_glyphs_(num_glyphs) { +} + +/****************************************************************************** + * LocaTable::Iterator class + ******************************************************************************/ +LocaTable::LocaIterator::LocaIterator(LocaTable* table) + : PODIterator<int32_t, LocaTable>(table), index_(-1) { +} + +bool LocaTable::LocaIterator::HasNext() { + return index_ <= container()->num_glyphs_; +} + +int32_t LocaTable::LocaIterator::Next() { + return container()->Loca(index_++); +} + +/****************************************************************************** + * LocaTable::Builder class + ******************************************************************************/ +LocaTable::Builder::Builder(Header* header, WritableFontData* data) + : Table::Builder(header, data), + format_version_(IndexToLocFormat::kLongOffset), + num_glyphs_(-1) { +} + +LocaTable::Builder::Builder(Header* header, ReadableFontData* data) + : Table::Builder(header, data), + format_version_(IndexToLocFormat::kLongOffset), + num_glyphs_(-1) { +} + +LocaTable::Builder::~Builder() {} + +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() { + return GetLocaList(); +} + +void LocaTable::Builder::SetLocaList(IntegerList* list) { + loca_.clear(); + if (list) { + loca_ = *list; + set_model_changed(); + } +} + +int32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) { + if (CheckGlyphRange(glyph_id) == -1) { + return 0; + } + return GetLocaList()->at(glyph_id); +} + +int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) { + if (CheckGlyphRange(glyph_id) == -1) { + return 0; + } + return GetLocaList()->at(glyph_id + 1) - GetLocaList()->at(glyph_id); +} + +void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) { + num_glyphs_ = num_glyphs; +} + +int32_t LocaTable::Builder::NumGlyphs() { + return LastGlyphIndex() - 1; +} + +void LocaTable::Builder::Revert() { + loca_.clear(); + set_model_changed(false); +} + +int32_t LocaTable::Builder::NumLocas() { + return GetLocaList()->size(); +} + +int32_t LocaTable::Builder::Loca(int32_t index) { + return GetLocaList()->at(index); +} + +CALLER_ATTACH +FontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) { + FontDataTablePtr table = + new LocaTable(header(), data, format_version_, num_glyphs_); + return table.Detach(); +} + +void LocaTable::Builder::SubDataSet() { + Initialize(InternalReadData()); +} + +int32_t LocaTable::Builder::SubDataSizeToSerialize() { + if (loca_.empty()) { + return 0; + } + if (format_version_ == IndexToLocFormat::kLongOffset) { + return loca_.size() * DataSize::kULONG; + } + return loca_.size() * DataSize::kUSHORT; +} + +bool LocaTable::Builder::SubReadyToSerialize() { + return !loca_.empty(); +} + +int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) { + int32_t size = 0; + for (IntegerList::iterator l = loca_.begin(), end = loca_.end(); + l != end; ++l) { + if (format_version_ == IndexToLocFormat::kLongOffset) { + size += new_data->WriteULong(size, *l); + } else { + size += new_data->WriteUShort(size, *l / 2); + } + } + num_glyphs_ = loca_.size() - 1; + return size; +} + +void LocaTable::Builder::Initialize(ReadableFontData* data) { + ClearLoca(false); + if (data) { + if (NumGlyphs() < 0) { +#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_); + Ptr<LocaTable::LocaIterator> loca_iter = + new LocaTable::LocaIterator(table); + while (loca_iter->HasNext()) { + loca_.push_back(loca_iter->Next()); + } + } +} + +int32_t LocaTable::Builder::CheckGlyphRange(int32_t glyph_id) { + if (glyph_id < 0 || glyph_id > LastGlyphIndex()) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException("Glyph ID is outside of the allowed range"); +#endif + return -1; + } + return glyph_id; +} + +int32_t LocaTable::Builder::LastGlyphIndex() { + return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1; +} + +IntegerList* LocaTable::Builder::GetLocaList() { + if (loca_.empty()) { + Initialize(InternalReadData()); + set_model_changed(); + } + return &loca_; +} + +void LocaTable::Builder::ClearLoca(bool nullify) { + // Note: in C++ port, nullify is not used at all. + UNREFERENCED_PARAMETER(nullify); + loca_.clear(); + set_model_changed(false); +} + +} // namespace sfntly |