diff options
Diffstat (limited to 'sfntly/table/bitmap/index_sub_table_format2.cc')
-rw-r--r-- | sfntly/table/bitmap/index_sub_table_format2.cc | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/sfntly/table/bitmap/index_sub_table_format2.cc b/sfntly/table/bitmap/index_sub_table_format2.cc new file mode 100644 index 0000000..ce73e9b --- /dev/null +++ b/sfntly/table/bitmap/index_sub_table_format2.cc @@ -0,0 +1,275 @@ +/* + * 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/bitmap/index_sub_table_format2.h" + +#include "sfntly/table/bitmap/eblc_table.h" + +namespace sfntly { +/****************************************************************************** + * IndexSubTableFormat2 class + ******************************************************************************/ +IndexSubTableFormat2::~IndexSubTableFormat2() { +} + +int32_t IndexSubTableFormat2::ImageSize() { + return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize); +} + +CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat2::BigMetrics() { + ReadableFontDataPtr slice; + slice.Attach(down_cast<ReadableFontData*>( + data_->Slice(EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics, + BigGlyphMetrics::Offset::kMetricsLength))); + BigGlyphMetricsPtr output = new BigGlyphMetrics(slice); + return output.Detach(); +} + +int32_t IndexSubTableFormat2::NumGlyphs() { + return last_glyph_index() - first_glyph_index() + 1; +} + +int32_t IndexSubTableFormat2::GlyphStartOffset(int32_t glyph_id) { + int32_t loca = CheckGlyphRange(glyph_id); + if (loca == -1) { + return -1; + } + return loca * image_size_; +} + +int32_t IndexSubTableFormat2::GlyphLength(int32_t glyph_id) { + if (CheckGlyphRange(glyph_id) == -1) { + return 0; + } + return image_size_; +} + +IndexSubTableFormat2::IndexSubTableFormat2(ReadableFontData* data, + int32_t first, + int32_t last) + : IndexSubTable(data, first, last) { + image_size_ = + data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize); +} + +/****************************************************************************** + * IndexSubTableFormat2::Builder class + ******************************************************************************/ +IndexSubTableFormat2::Builder::~Builder() { +} + +int32_t IndexSubTableFormat2::Builder::NumGlyphs() { + return last_glyph_index() - first_glyph_index() + 1; +} + +int32_t IndexSubTableFormat2::Builder::GlyphStartOffset(int32_t glyph_id) { + int32_t loca = CheckGlyphRange(glyph_id); + if (loca == -1) { + return -1; + } + return loca * ImageSize(); +} + +int32_t IndexSubTableFormat2::Builder::GlyphLength(int32_t glyph_id) { + int32_t loca = CheckGlyphRange(glyph_id); + if (loca == -1) { + return 0; + } + return ImageSize(); +} + +CALLER_ATTACH IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* + IndexSubTableFormat2::Builder::GetIterator() { + Ptr<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator> it = + new IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator(this); + return it.Detach(); +} + +int32_t IndexSubTableFormat2::Builder::ImageSize() { + return InternalReadData()->ReadULongAsInt( + EblcTable::Offset::kIndexSubTable2_imageSize); +} + +void IndexSubTableFormat2::Builder::SetImageSize(int32_t image_size) { + InternalWriteData()->WriteULong(EblcTable::Offset::kIndexSubTable2_imageSize, + image_size); +} + +BigGlyphMetrics::Builder* IndexSubTableFormat2::Builder::BigMetrics() { + if (metrics_ == NULL) { + WritableFontDataPtr data; + data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice( + EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics, + BigGlyphMetrics::Offset::kMetricsLength))); + metrics_ = new BigGlyphMetrics::Builder(data); + } + return metrics_; +} + +// static +CALLER_ATTACH IndexSubTableFormat2::Builder* +IndexSubTableFormat2::Builder::CreateBuilder() { + IndexSubTableFormat2BuilderPtr output = new IndexSubTableFormat2::Builder(); + return output.Detach(); +} + +// static +CALLER_ATTACH IndexSubTableFormat2::Builder* +IndexSubTableFormat2::Builder::CreateBuilder(ReadableFontData* data, + int32_t index_sub_table_offset, + int32_t first_glyph_index, + int32_t last_glyph_index) { + int32_t length = Builder::DataLength(data, + index_sub_table_offset, + first_glyph_index, + last_glyph_index); + ReadableFontDataPtr new_data; + new_data.Attach(down_cast<ReadableFontData*>( + data->Slice(index_sub_table_offset, length))); + if (new_data == NULL) { + return NULL; + } + IndexSubTableFormat2BuilderPtr output = + new IndexSubTableFormat2::Builder(new_data, + first_glyph_index, + last_glyph_index); + return output.Detach(); +} + +// static +CALLER_ATTACH IndexSubTableFormat2::Builder* +IndexSubTableFormat2::Builder::CreateBuilder(WritableFontData* data, + int32_t index_sub_table_offset, + int32_t first_glyph_index, + int32_t last_glyph_index) { + int32_t length = Builder::DataLength(data, + index_sub_table_offset, + first_glyph_index, + last_glyph_index); + WritableFontDataPtr new_data; + new_data.Attach(down_cast<WritableFontData*>( + data->Slice(index_sub_table_offset, length))); + IndexSubTableFormat2BuilderPtr output = + new IndexSubTableFormat2::Builder(new_data, + first_glyph_index, + last_glyph_index); + return output.Detach(); +} + +CALLER_ATTACH FontDataTable* IndexSubTableFormat2::Builder::SubBuildTable( + ReadableFontData* data) { + IndexSubTableFormat2Ptr output = new IndexSubTableFormat2( + data, first_glyph_index(), last_glyph_index()); + return output.Detach(); +} + +void IndexSubTableFormat2::Builder::SubDataSet() { + Revert(); +} + +int32_t IndexSubTableFormat2::Builder::SubDataSizeToSerialize() { + return EblcTable::Offset::kIndexSubTable2Length; +} + +bool IndexSubTableFormat2::Builder::SubReadyToSerialize() { + return true; +} + +int32_t IndexSubTableFormat2::Builder::SubSerialize( + WritableFontData* new_data) { + int32_t size = SerializeIndexSubHeader(new_data); + if (metrics_ == NULL) { + ReadableFontDataPtr source; + WritableFontDataPtr target; + source.Attach(down_cast<ReadableFontData*>( + InternalReadData()->Slice(size))); + target.Attach(down_cast<WritableFontData*>(new_data->Slice(size))); + size += source->CopyTo(target); + } else { + WritableFontDataPtr slice; + size += new_data->WriteLong(EblcTable::Offset::kIndexSubTable2_imageSize, + ImageSize()); + slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size))); + size += metrics_->SubSerialize(slice); + } + return size; +} + +IndexSubTableFormat2::Builder::Builder() + : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize, + IndexSubTable::Format::FORMAT_2) { + metrics_.Attach(BigGlyphMetrics::Builder::CreateBuilder()); +} + +IndexSubTableFormat2::Builder::Builder(WritableFontData* data, + int32_t first_glyph_index, + int32_t last_glyph_index) + : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) { +} + +IndexSubTableFormat2::Builder::Builder(ReadableFontData* data, + int32_t first_glyph_index, + int32_t last_glyph_index) + : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) { +} + +// static +int32_t IndexSubTableFormat2::Builder::DataLength( + ReadableFontData* data, + int32_t index_sub_table_offset, + int32_t first_glyph_index, + int32_t last_glyph_index) { + UNREFERENCED_PARAMETER(data); + UNREFERENCED_PARAMETER(index_sub_table_offset); + UNREFERENCED_PARAMETER(first_glyph_index); + UNREFERENCED_PARAMETER(last_glyph_index); + return EblcTable::Offset::kIndexSubTable2Length; +} + +/****************************************************************************** + * IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator class + ******************************************************************************/ +IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator( + IndexSubTableFormat2::Builder* container) + : RefIterator<BitmapGlyphInfo, IndexSubTableFormat2::Builder, + IndexSubTable::Builder>(container) { + glyph_id_ = container->first_glyph_index(); +} + +bool IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::HasNext() { + if (glyph_id_ <= container()->last_glyph_index()) { + return true; + } + return false; +} + +CALLER_ATTACH BitmapGlyphInfo* +IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::Next() { + BitmapGlyphInfoPtr output; + if (!HasNext()) { + // Note: In C++, we do not throw exception when there's no element. + return NULL; + } + output = new BitmapGlyphInfo(glyph_id_, + container()->image_data_offset(), + container()->GlyphStartOffset(glyph_id_), + container()->GlyphLength(glyph_id_), + container()->image_format()); + glyph_id_++; + return output.Detach(); +} + +} // namespace sfntly |