diff options
author | arthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51> | 2011-10-11 01:01:16 +0000 |
---|---|---|
committer | arthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51> | 2011-10-11 01:01:16 +0000 |
commit | 333edd91cb32d6acfd0307ba2ae8f60baed75ff4 (patch) | |
tree | e2cd71c762d6105ef3fb8dafa5b08a109fe01c7f /sfntly/table/bitmap/eblc_table.cc | |
parent | dc47db9a1c26e13a4e8be6185bd0ecf89c0d1f81 (diff) | |
download | src-333edd91cb32d6acfd0307ba2ae8f60baed75ff4.tar.gz |
Update to Sep 30 snapshot, include all current EBXX support.
Refine Iterator ports: all java-style Iterator objects are ref-counted and have automatic memory management now.
git-svn-id: http://sfntly.googlecode.com/svn/trunk/cpp/src@100 672e30a5-4c29-85ac-ac6d-611c735e0a51
Diffstat (limited to 'sfntly/table/bitmap/eblc_table.cc')
-rw-r--r-- | sfntly/table/bitmap/eblc_table.cc | 199 |
1 files changed, 192 insertions, 7 deletions
diff --git a/sfntly/table/bitmap/eblc_table.cc b/sfntly/table/bitmap/eblc_table.cc index decbadf..bb36db0 100644 --- a/sfntly/table/bitmap/eblc_table.cc +++ b/sfntly/table/bitmap/eblc_table.cc @@ -16,6 +16,10 @@ #include "sfntly/table/bitmap/eblc_table.h" +#include <stdlib.h> + +#include "sfntly/math/font_math.h" + namespace sfntly { /****************************************************************************** * EblcTable class @@ -67,8 +71,12 @@ void EblcTable::CreateBitmapSizeTable(ReadableFontData* data, data->Slice(Offset::kBitmapSizeTableArrayStart + i * Offset::kBitmapSizeTableLength, Offset::kBitmapSizeTableLength))); - BitmapSizeTablePtr new_table = new BitmapSizeTable(new_data, data); - output->push_back(new_table); + BitmapSizeTableBuilderPtr size_builder; + size_builder.Attach( + BitmapSizeTable::Builder::CreateBuilder(new_data, data)); + BitmapSizeTablePtr size; + size.Attach(down_cast<BitmapSizeTable*>(size_builder->Build())); + output->push_back(size); } } @@ -87,20 +95,163 @@ EblcTable::Builder::~Builder() { } int32_t EblcTable::Builder::SubSerialize(WritableFontData* new_data) { - UNREFERENCED_PARAMETER(new_data); - return 0; + // header + int32_t size = new_data->WriteFixed(0, kVersion); + size += new_data->WriteULong(size, size_table_builders_.size()); + + // calculate the offsets + // offset to the start of the size table array + int32_t size_table_start_offset = size; + // walking offset in the size table array + int32_t size_table_offset = size_table_start_offset; + // offset to the start of the whole index subtable block + int32_t sub_table_block_start_offset = size_table_offset + + size_table_builders_.size() * Offset::kBitmapSizeTableLength; + // walking offset in the index subtable + // points to the start of the current subtable block + int32_t current_sub_table_block_start_offset = sub_table_block_start_offset; + +#if defined (SFNTLY_DEBUG_BITMAP) + int32_t size_index = 0; +#endif + for (BitmapSizeTableBuilderList::iterator + size_builder = size_table_builders_.begin(), + size_builder_end = size_table_builders_.end(); + size_builder != size_builder_end; size_builder++) { + (*size_builder)->SetIndexSubTableArrayOffset( + current_sub_table_block_start_offset); + IndexSubTableBuilderList* index_sub_table_builder_list = + (*size_builder)->IndexSubTableBuilders(); + + // walking offset within the current subTable array + int32_t index_sub_table_array_offset = current_sub_table_block_start_offset; + // walking offset within the subTable entries + int32_t index_sub_table_offset = index_sub_table_array_offset + + index_sub_table_builder_list->size() * Offset::kIndexSubHeaderLength; + +#if defined (SFNTLY_DEBUG_BITMAP) + fprintf(stderr, "size %d: sizeTable=%x, current subTable Block=%x, ", + size_index, size_table_offset); + fprintf(stderr, "index subTableStart=%x\n", index_sub_table_offset); + size_index++; + int32_t sub_table_index = 0; +#endif + for (IndexSubTableBuilderList::iterator + index_sub_table_builder = index_sub_table_builder_list->begin(), + index_sub_table_builder_end = index_sub_table_builder_list->end(); + index_sub_table_builder != index_sub_table_builder_end; + index_sub_table_builder++) { +#if defined (SFNTLY_DEBUG_BITMAP) + fprintf(stderr, "\tsubTableIndex %d: format=%x, ", sub_table_index, + (*index_sub_table_builder)->index_format()); + fprintf(stderr, "indexSubTableArrayOffset=%x, indexSubTableOffset=%x\n", + index_sub_table_array_offset, index_sub_table_offset); + sub_table_index++; +#endif + // array entry + index_sub_table_array_offset += new_data->WriteUShort( + index_sub_table_array_offset, + (*index_sub_table_builder)->first_glyph_index()); + index_sub_table_array_offset += new_data->WriteUShort( + index_sub_table_array_offset, + (*index_sub_table_builder)->last_glyph_index()); + index_sub_table_array_offset += new_data->WriteULong( + index_sub_table_array_offset, + index_sub_table_offset - current_sub_table_block_start_offset); + + // index sub table + WritableFontDataPtr slice_index_sub_table; + slice_index_sub_table.Attach(down_cast<WritableFontData*>( + new_data->Slice(index_sub_table_offset))); + int32_t current_sub_table_size = + (*index_sub_table_builder)->SubSerialize(slice_index_sub_table); + int32_t padding = FontMath::PaddingRequired(current_sub_table_size, + DataSize::kULONG); +#if defined (SFNTLY_DEBUG_BITMAP) + fprintf(stderr, "\t\tsubTableSize = %x, padding = %x\n", + current_sub_table_size, padding); +#endif + index_sub_table_offset += current_sub_table_size; + index_sub_table_offset += + new_data->WritePadding(index_sub_table_offset, padding); + } + + // serialize size table + (*size_builder)->SetIndexTableSize( + index_sub_table_offset - current_sub_table_block_start_offset); + WritableFontDataPtr slice_size_table; + slice_size_table.Attach(down_cast<WritableFontData*>( + new_data->Slice(size_table_offset))); + size_table_offset += (*size_builder)->SubSerialize(slice_size_table); + + current_sub_table_block_start_offset = index_sub_table_offset; + } + return size + current_sub_table_block_start_offset; } bool EblcTable::Builder::SubReadyToSerialize() { - return false; + if (size_table_builders_.empty()) { + return false; + } + for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(), + e = size_table_builders_.end(); + b != e; b++) { + if (!(*b)->SubReadyToSerialize()) { + return false; + } + } + return true; } int32_t EblcTable::Builder::SubDataSizeToSerialize() { - return 0; + if (size_table_builders_.empty()) { + return 0; + } + int32_t size = Offset::kHeaderLength; + bool variable = false; + for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(), + e = size_table_builders_.end(); + b != e; b++) { + int32_t size_builder_size = (*b)->SubDataSizeToSerialize(); + variable = size_builder_size > 0 ? variable : true; + size += abs(size_builder_size); + } + return -size; + // TODO(stuartg): need to fix to get size calculated accurately + // return variable ? -size : size; } void EblcTable::Builder::SubDataSet() { - // NOP + Revert(); +} + +BitmapSizeTableBuilderList* EblcTable::Builder::BitmapSizeBuilders() { + return GetSizeList(); +} + +void EblcTable::Builder::Revert() { + size_table_builders_.clear(); + set_model_changed(false); +} + +void EblcTable::Builder::GenerateLocaList(BitmapLocaList* output) { + assert(output); + BitmapSizeTableBuilderList* size_builder_list = GetSizeList(); + output->clear(); + output->resize(size_builder_list->size()); +#if defined (SFNTLY_DEBUG_BITMAP) + int32_t size_index = 0; +#endif + for (BitmapSizeTableBuilderList::iterator b = size_builder_list->begin(), + e = size_builder_list->end(); + b != e; b++) { +#if defined (SFNTLY_DEBUG_BITMAP) + fprintf(stderr, "size table = %d\n", size_index++); +#endif + BitmapGlyphInfoMap loca_map; + (*b)->GenerateLocaMap(&loca_map); + output->push_back(loca_map); + } } CALLER_ATTACH @@ -116,4 +267,38 @@ CALLER_ATTACH EblcTable::Builder* return new_builder.Detach(); } +// static +CALLER_ATTACH EblcTable::Builder* + EblcTable::Builder::CreateBuilder(Header* header, ReadableFontData* data) { + Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data); + return new_builder.Detach(); +} + +BitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() { + if (size_table_builders_.empty()) { + Initialize(InternalReadData(), &size_table_builders_); + set_model_changed(); + } + return &size_table_builders_; +} + +void EblcTable::Builder::Initialize(ReadableFontData* data, + BitmapSizeTableBuilderList* output) { + assert(output); + if (data) { + int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes); + for (int32_t i = 0; i < num_sizes; ++i) { + ReadableFontDataPtr new_data; + new_data.Attach(down_cast<ReadableFontData*>( + data->Slice(Offset::kBitmapSizeTableArrayStart + + i * Offset::kBitmapSizeTableLength, + Offset::kBitmapSizeTableLength))); + BitmapSizeTableBuilderPtr size_builder; + size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder( + new_data, data)); + output->push_back(size_builder); + } + } +} + } // namespace sfntly |