16b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com/*
26b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
36b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com *
46b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
56b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * you may not use this file except in compliance with the License.
66b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * You may obtain a copy of the License at
76b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com *
86b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
96b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com *
106b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
116b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
126b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * See the License for the specific language governing permissions and
146b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com * limitations under the License.
156b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com */
166b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
176b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com#include "sfntly/table/bitmap/index_sub_table_format5.h"
186b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
19333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com#include <algorithm>
20333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
216b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com#include "sfntly/table/bitmap/eblc_table.h"
226b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
236b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.comnamespace sfntly {
24333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com/******************************************************************************
25333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com * IndexSubTableFormat5 class
26333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com ******************************************************************************/
27333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::~IndexSubTableFormat5() {
28333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
296b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
30333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::NumGlyphs() {
31333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return NumGlyphs(data_, 0);
32333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
33333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
34333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::GlyphStartOffset(int32_t glyph_id) {
35333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t check = CheckGlyphRange(glyph_id);
36333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (check == -1) {
37333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return -1;
38333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
39333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t loca = ReadFontData()->SearchUShort(
40333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_glyphArray,
41333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      DataSize::kUSHORT,
42333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      NumGlyphs(),
43333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      glyph_id);
44333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (loca == -1) {
45333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return loca;
46333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
47333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return loca * ImageSize();
48333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
49333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
50333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::GlyphLength(int32_t glyph_id) {
51333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t check = CheckGlyphRange(glyph_id);
52333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (check == -1) {
53333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return 0;
54333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
55333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return image_size_;
56333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
57333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
58333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::ImageSize() {
59333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable5_imageSize);
60333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
61333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
62333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat5::BigMetrics() {
63333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  ReadableFontDataPtr data;
64333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  data.Attach(down_cast<ReadableFontData*>(data_->Slice(
6553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
66333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      BigGlyphMetrics::Offset::kMetricsLength)));
67333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
68333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
696b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
706b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
716b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.comIndexSubTableFormat5::IndexSubTableFormat5(ReadableFontData* data,
72333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                           int32_t first_glyph_index,
73333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                           int32_t last_glyph_index)
74333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : IndexSubTable(data, first_glyph_index, last_glyph_index) {
75333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  image_size_ = data_->ReadULongAsInt(
76333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_imageSize);
776b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
786b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
79333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com// static
80333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::NumGlyphs(ReadableFontData* data,
81333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                        int32_t table_offset) {
82be87cfe77f08387d23cabc3a403fa53531b687a8arthurhsu@google.com  int32_t num_glyphs = data->ReadULongAsInt(table_offset +
83333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_numGlyphs);
84333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return num_glyphs;
856b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
866b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
87333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com/******************************************************************************
88333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com * IndexSubTableFormat5::Builder class
89333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com ******************************************************************************/
90333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::~Builder() {
916b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
926b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
93333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::NumGlyphs() {
94333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return GetGlyphArray()->size();
95333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
96333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
97333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::GlyphLength(int32_t glyph_id) {
98333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  UNREFERENCED_PARAMETER(glyph_id);
99333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return ImageSize();
100333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
101333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
102333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::GlyphStartOffset(int32_t glyph_id) {
103333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t check = CheckGlyphRange(glyph_id);
104333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (check == -1) {
105333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return -1;
106333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
107333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IntegerList* glyph_array = GetGlyphArray();
108333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IntegerList::iterator it = std::find(glyph_array->begin(),
109333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       glyph_array->end(),
110333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       glyph_id);
111333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (it == glyph_array->end()) {
112333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return -1;
1136b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com  }
114333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return (it - glyph_array->begin()) * ImageSize();
1156b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
1166b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
117be87cfe77f08387d23cabc3a403fa53531b687a8arthurhsu@google.comCALLER_ATTACH IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*
118be87cfe77f08387d23cabc3a403fa53531b687a8arthurhsu@google.com    IndexSubTableFormat5::Builder::GetIterator() {
119333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  Ptr<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator> it =
120333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      new IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator(this);
121333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return it.Detach();
122333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
123333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
124333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com// static
125333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH IndexSubTableFormat5::Builder*
12653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.comIndexSubTableFormat5::Builder::CreateBuilder() {
12753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  IndexSubTableFormat5BuilderPtr output = new IndexSubTableFormat5::Builder();
12853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  return output.Detach();
12953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com}
13053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
13153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com// static
13253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.comCALLER_ATTACH IndexSubTableFormat5::Builder*
133333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::CreateBuilder(ReadableFontData* data,
134333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t index_sub_table_offset,
135333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t first_glyph_index,
136333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t last_glyph_index) {
137333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t length = Builder::DataLength(data,
138333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       index_sub_table_offset,
139333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       first_glyph_index,
140333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       last_glyph_index);
141333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  ReadableFontDataPtr new_data;
142333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  new_data.Attach(down_cast<ReadableFontData*>(
143333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      data->Slice(index_sub_table_offset, length)));
144127cef2a54a5b6e6777761d550c1ec90e736383farthurhsu@google.com  if (new_data == NULL) {
145127cef2a54a5b6e6777761d550c1ec90e736383farthurhsu@google.com    return NULL;
146127cef2a54a5b6e6777761d550c1ec90e736383farthurhsu@google.com  }
147333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IndexSubTableFormat5BuilderPtr output =
148333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      new IndexSubTableFormat5::Builder(new_data,
149333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                        first_glyph_index,
150333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                        last_glyph_index);
151333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
152333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
153333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
154333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com// static
155333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH IndexSubTableFormat5::Builder*
156333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::CreateBuilder(WritableFontData* data,
157333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t index_sub_table_offset,
158333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t first_glyph_index,
159333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                             int32_t last_glyph_index) {
160333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t length = Builder::DataLength(data,
161333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       index_sub_table_offset,
162333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       first_glyph_index,
163333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       last_glyph_index);
164333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  WritableFontDataPtr new_data;
165333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  new_data.Attach(down_cast<WritableFontData*>(
166333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      data->Slice(index_sub_table_offset, length)));
167333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IndexSubTableFormat5BuilderPtr output =
168333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      new IndexSubTableFormat5::Builder(new_data,
169333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                        first_glyph_index,
170333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                        last_glyph_index);
171333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
172333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
173333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
174333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH FontDataTable* IndexSubTableFormat5::Builder::SubBuildTable(
175333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    ReadableFontData* data) {
176333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IndexSubTableFormat5Ptr output = new IndexSubTableFormat5(
177333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      data, first_glyph_index(), last_glyph_index());
178333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
179333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
180333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
181333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comvoid IndexSubTableFormat5::Builder::SubDataSet() {
18253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  Revert();
183333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
184333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
185333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::SubDataSizeToSerialize() {
186333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (glyph_array_.empty()) {
18753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    return InternalReadData()->Length();
188333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
18953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  return EblcTable::Offset::kIndexSubTable5_builderDataSize +
190333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com         glyph_array_.size() * DataSize::kUSHORT;
191333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
192333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
193333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.combool IndexSubTableFormat5::Builder::SubReadyToSerialize() {
194333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (!glyph_array_.empty()) {
195333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return true;
196333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
197333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return false;
198333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
199333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
200333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::SubSerialize(
201333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    WritableFontData* new_data) {
202333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t size = SerializeIndexSubHeader(new_data);
203333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (!model_changed()) {
204333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    ReadableFontDataPtr source;
205333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    WritableFontDataPtr target;
206333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
207333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com        EblcTable::Offset::kIndexSubTable5_imageSize)));
208333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    target.Attach(down_cast<WritableFontData*>(new_data->Slice(
209333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com        EblcTable::Offset::kIndexSubTable5_imageSize)));
210333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    size += source->CopyTo(target);
211333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  } else {
21253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    size += new_data->WriteULong(EblcTable::Offset::kIndexSubTable5_imageSize,
21353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com                                 ImageSize());
21453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    WritableFontDataPtr slice;
21553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
21653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    size += BigMetrics()->SubSerialize(slice);
21753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    size += new_data->WriteULong(size, glyph_array_.size());
21853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
21953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com                               b != e; b++) {
22053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com      size += new_data->WriteUShort(size, *b);
22153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    }
222333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
223333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return size;
224333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
225333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
226333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::ImageSize() {
227333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return InternalReadData()->ReadULongAsInt(
228333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_imageSize);
229333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
230333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
231333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comvoid IndexSubTableFormat5::Builder::SetImageSize(int32_t image_size) {
232333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  InternalWriteData()->WriteULong(
233333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      EblcTable::Offset::kIndexSubTable5_imageSize, image_size);
234333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
235333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
236333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comBigGlyphMetrics::Builder* IndexSubTableFormat5::Builder::BigMetrics() {
23753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  if (metrics_ == NULL) {
23853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    WritableFontDataPtr data;
23953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
24053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com        EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
24153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com        BigGlyphMetrics::Offset::kMetricsLength)));
24253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    metrics_ = new BigGlyphMetrics::Builder(data);
24353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    set_model_changed();
24453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  }
24553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  return metrics_;
246333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
247333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
248333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
249333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return GetGlyphArray();
250333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
251333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
252333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comvoid IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
253333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  glyph_array_.clear();
254333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  glyph_array_ = v;
255333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  set_model_changed();
256333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
257333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
258333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comvoid IndexSubTableFormat5::Builder::Revert() {
259333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  glyph_array_.clear();
260333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  IndexSubTable::Builder::Revert();
261333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
262333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
26353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.comIndexSubTableFormat5::Builder::Builder()
26453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable5_builderDataSize,
26553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com                             IndexSubTable::Format::FORMAT_5) {
26653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com}
26753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
268333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::Builder(WritableFontData* data,
269333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       int32_t first_glyph_index,
270333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       int32_t last_glyph_index)
271333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
272333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
273333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
274333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::Builder(ReadableFontData* data,
275333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       int32_t first_glyph_index,
276333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                       int32_t last_glyph_index)
277333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
278333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
279333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
280333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
281333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (glyph_array_.empty()) {
282333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    Initialize(InternalReadData());
283333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    set_model_changed();
284333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
285333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return &glyph_array_;
286333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
287333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
288333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comvoid IndexSubTableFormat5::Builder::Initialize(ReadableFontData* data) {
289333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  glyph_array_.clear();
290333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (data) {
291333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data, 0);
292333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    for (int32_t i = 0; i < num_glyphs; ++i) {
293be87cfe77f08387d23cabc3a403fa53531b687a8arthurhsu@google.com      glyph_array_.push_back(data->ReadUShort(
294333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com          EblcTable::Offset::kIndexSubTable5_glyphArray +
295333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com          i * DataSize::kUSHORT));
296333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    }
297333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
298333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
299333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
300333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com// static
301333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comint32_t IndexSubTableFormat5::Builder::DataLength(
302333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    ReadableFontData* data,
303333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    int32_t index_sub_table_offset,
304333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    int32_t first_glyph_index,
305333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    int32_t last_glyph_index) {
306333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data,
307333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                                                       index_sub_table_offset);
308333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  UNREFERENCED_PARAMETER(first_glyph_index);
309333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  UNREFERENCED_PARAMETER(last_glyph_index);
310333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return EblcTable::Offset::kIndexSubTable5_glyphArray +
311333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com         num_glyphs * DataSize::kUSHORT;
312333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
313333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
314333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com/******************************************************************************
315333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com * IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator class
316333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com ******************************************************************************/
317333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
318333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    IndexSubTableFormat5::Builder* container)
319333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    : RefIterator<BitmapGlyphInfo, IndexSubTableFormat5::Builder,
320333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                  IndexSubTable::Builder>(container),
321333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com      offset_index_(0) {
322333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
323333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
324333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.combool IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::HasNext() {
325333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (offset_index_ < (int32_t)(container()->GetGlyphArray()->size())) {
326333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return true;
327333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  }
328333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return false;
329333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com}
330333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com
331333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comCALLER_ATTACH BitmapGlyphInfo*
332333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.comIndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::Next() {
333333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  BitmapGlyphInfoPtr output;
334333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  if (!HasNext()) {
335333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    // Note: In C++, we do not throw exception when there's no element.
336333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com    return NULL;
3376b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com  }
338333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  output = new BitmapGlyphInfo(container()->GetGlyphArray()->at(offset_index_),
339333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                               container()->image_data_offset(),
340333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                               offset_index_ * container()->ImageSize(),
341333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                               container()->ImageSize(),
342333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com                               container()->image_format());
343333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  offset_index_++;
344333edd91cb32d6acfd0307ba2ae8f60baed75ff4arthurhsu@google.com  return output.Detach();
3456b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}
3466b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com
3476b8e073e978eed96605da6f92d6db740a39864baarthurhsu@google.com}  // namespace sfntly
348