Line data Source code
1 : /*
2 : * Copyright 2011 Google Inc. All Rights Reserved.
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #include "sfntly/table/bitmap/index_sub_table_format2.h"
18 :
19 : #include "sfntly/table/bitmap/eblc_table.h"
20 :
21 : namespace sfntly {
22 : /******************************************************************************
23 : * IndexSubTableFormat2 class
24 : ******************************************************************************/
25 0 : IndexSubTableFormat2::~IndexSubTableFormat2() {
26 0 : }
27 :
28 0 : int32_t IndexSubTableFormat2::ImageSize() {
29 0 : return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
30 : }
31 :
32 0 : CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat2::BigMetrics() {
33 0 : ReadableFontDataPtr slice;
34 0 : slice.Attach(down_cast<ReadableFontData*>(
35 0 : data_->Slice(EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
36 0 : BigGlyphMetrics::Offset::kMetricsLength)));
37 0 : BigGlyphMetricsPtr output = new BigGlyphMetrics(slice);
38 0 : return output.Detach();
39 : }
40 :
41 0 : int32_t IndexSubTableFormat2::NumGlyphs() {
42 0 : return last_glyph_index() - first_glyph_index() + 1;
43 : }
44 :
45 0 : int32_t IndexSubTableFormat2::GlyphStartOffset(int32_t glyph_id) {
46 0 : int32_t loca = CheckGlyphRange(glyph_id);
47 0 : if (loca == -1) {
48 0 : return -1;
49 : }
50 0 : return loca * image_size_;
51 : }
52 :
53 0 : int32_t IndexSubTableFormat2::GlyphLength(int32_t glyph_id) {
54 0 : if (CheckGlyphRange(glyph_id) == -1) {
55 0 : return 0;
56 : }
57 0 : return image_size_;
58 : }
59 :
60 0 : IndexSubTableFormat2::IndexSubTableFormat2(ReadableFontData* data,
61 : int32_t first,
62 0 : int32_t last)
63 0 : : IndexSubTable(data, first, last) {
64 0 : image_size_ =
65 0 : data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
66 0 : }
67 :
68 : /******************************************************************************
69 : * IndexSubTableFormat2::Builder class
70 : ******************************************************************************/
71 0 : IndexSubTableFormat2::Builder::~Builder() {
72 0 : }
73 :
74 0 : int32_t IndexSubTableFormat2::Builder::NumGlyphs() {
75 0 : return last_glyph_index() - first_glyph_index() + 1;
76 : }
77 :
78 0 : int32_t IndexSubTableFormat2::Builder::GlyphStartOffset(int32_t glyph_id) {
79 0 : int32_t loca = CheckGlyphRange(glyph_id);
80 0 : if (loca == -1) {
81 0 : return -1;
82 : }
83 0 : return loca * ImageSize();
84 : }
85 :
86 0 : int32_t IndexSubTableFormat2::Builder::GlyphLength(int32_t glyph_id) {
87 0 : int32_t loca = CheckGlyphRange(glyph_id);
88 0 : if (loca == -1) {
89 0 : return 0;
90 : }
91 0 : return ImageSize();
92 : }
93 :
94 : CALLER_ATTACH IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*
95 0 : IndexSubTableFormat2::Builder::GetIterator() {
96 : Ptr<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator> it =
97 0 : new IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator(this);
98 0 : return it.Detach();
99 : }
100 :
101 0 : int32_t IndexSubTableFormat2::Builder::ImageSize() {
102 0 : return InternalReadData()->ReadULongAsInt(
103 0 : EblcTable::Offset::kIndexSubTable2_imageSize);
104 : }
105 :
106 0 : void IndexSubTableFormat2::Builder::SetImageSize(int32_t image_size) {
107 0 : InternalWriteData()->WriteULong(EblcTable::Offset::kIndexSubTable2_imageSize,
108 0 : image_size);
109 0 : }
110 :
111 0 : BigGlyphMetrics::Builder* IndexSubTableFormat2::Builder::BigMetrics() {
112 0 : if (metrics_ == NULL) {
113 0 : WritableFontDataPtr data;
114 0 : data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
115 : EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
116 0 : BigGlyphMetrics::Offset::kMetricsLength)));
117 0 : metrics_ = new BigGlyphMetrics::Builder(data);
118 : }
119 0 : return metrics_;
120 : }
121 :
122 : // static
123 : CALLER_ATTACH IndexSubTableFormat2::Builder*
124 0 : IndexSubTableFormat2::Builder::CreateBuilder() {
125 0 : IndexSubTableFormat2BuilderPtr output = new IndexSubTableFormat2::Builder();
126 0 : return output.Detach();
127 : }
128 :
129 : // static
130 : CALLER_ATTACH IndexSubTableFormat2::Builder*
131 0 : IndexSubTableFormat2::Builder::CreateBuilder(ReadableFontData* data,
132 : int32_t index_sub_table_offset,
133 : int32_t first_glyph_index,
134 : int32_t last_glyph_index) {
135 : int32_t length = Builder::DataLength(data,
136 : index_sub_table_offset,
137 : first_glyph_index,
138 0 : last_glyph_index);
139 0 : ReadableFontDataPtr new_data;
140 0 : new_data.Attach(down_cast<ReadableFontData*>(
141 0 : data->Slice(index_sub_table_offset, length)));
142 0 : if (new_data == NULL) {
143 0 : return NULL;
144 : }
145 : IndexSubTableFormat2BuilderPtr output =
146 : new IndexSubTableFormat2::Builder(new_data,
147 : first_glyph_index,
148 0 : last_glyph_index);
149 0 : return output.Detach();
150 : }
151 :
152 : // static
153 : CALLER_ATTACH IndexSubTableFormat2::Builder*
154 0 : IndexSubTableFormat2::Builder::CreateBuilder(WritableFontData* data,
155 : int32_t index_sub_table_offset,
156 : int32_t first_glyph_index,
157 : int32_t last_glyph_index) {
158 : int32_t length = Builder::DataLength(data,
159 : index_sub_table_offset,
160 : first_glyph_index,
161 0 : last_glyph_index);
162 0 : WritableFontDataPtr new_data;
163 0 : new_data.Attach(down_cast<WritableFontData*>(
164 0 : data->Slice(index_sub_table_offset, length)));
165 : IndexSubTableFormat2BuilderPtr output =
166 : new IndexSubTableFormat2::Builder(new_data,
167 : first_glyph_index,
168 0 : last_glyph_index);
169 0 : return output.Detach();
170 : }
171 :
172 0 : CALLER_ATTACH FontDataTable* IndexSubTableFormat2::Builder::SubBuildTable(
173 : ReadableFontData* data) {
174 : IndexSubTableFormat2Ptr output = new IndexSubTableFormat2(
175 0 : data, first_glyph_index(), last_glyph_index());
176 0 : return output.Detach();
177 : }
178 :
179 0 : void IndexSubTableFormat2::Builder::SubDataSet() {
180 0 : Revert();
181 0 : }
182 :
183 0 : int32_t IndexSubTableFormat2::Builder::SubDataSizeToSerialize() {
184 0 : return EblcTable::Offset::kIndexSubTable2Length;
185 : }
186 :
187 0 : bool IndexSubTableFormat2::Builder::SubReadyToSerialize() {
188 0 : return true;
189 : }
190 :
191 0 : int32_t IndexSubTableFormat2::Builder::SubSerialize(
192 : WritableFontData* new_data) {
193 0 : int32_t size = SerializeIndexSubHeader(new_data);
194 0 : if (metrics_ == NULL) {
195 0 : ReadableFontDataPtr source;
196 0 : WritableFontDataPtr target;
197 0 : source.Attach(down_cast<ReadableFontData*>(
198 0 : InternalReadData()->Slice(size)));
199 0 : target.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
200 0 : size += source->CopyTo(target);
201 : } else {
202 0 : WritableFontDataPtr slice;
203 0 : size += new_data->WriteLong(EblcTable::Offset::kIndexSubTable2_imageSize,
204 0 : ImageSize());
205 0 : slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
206 0 : size += metrics_->SubSerialize(slice);
207 : }
208 0 : return size;
209 : }
210 :
211 0 : IndexSubTableFormat2::Builder::Builder()
212 : : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
213 0 : IndexSubTable::Format::FORMAT_2) {
214 0 : metrics_.Attach(BigGlyphMetrics::Builder::CreateBuilder());
215 0 : }
216 :
217 0 : IndexSubTableFormat2::Builder::Builder(WritableFontData* data,
218 : int32_t first_glyph_index,
219 0 : int32_t last_glyph_index)
220 0 : : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
221 0 : }
222 :
223 0 : IndexSubTableFormat2::Builder::Builder(ReadableFontData* data,
224 : int32_t first_glyph_index,
225 0 : int32_t last_glyph_index)
226 0 : : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
227 0 : }
228 :
229 : // static
230 0 : int32_t IndexSubTableFormat2::Builder::DataLength(
231 : ReadableFontData* data,
232 : int32_t index_sub_table_offset,
233 : int32_t first_glyph_index,
234 : int32_t last_glyph_index) {
235 : UNREFERENCED_PARAMETER(data);
236 : UNREFERENCED_PARAMETER(index_sub_table_offset);
237 : UNREFERENCED_PARAMETER(first_glyph_index);
238 : UNREFERENCED_PARAMETER(last_glyph_index);
239 0 : return EblcTable::Offset::kIndexSubTable2Length;
240 : }
241 :
242 : /******************************************************************************
243 : * IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator class
244 : ******************************************************************************/
245 0 : IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
246 0 : IndexSubTableFormat2::Builder* container)
247 : : RefIterator<BitmapGlyphInfo, IndexSubTableFormat2::Builder,
248 0 : IndexSubTable::Builder>(container) {
249 0 : glyph_id_ = container->first_glyph_index();
250 0 : }
251 :
252 0 : bool IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::HasNext() {
253 0 : if (glyph_id_ <= container()->last_glyph_index()) {
254 0 : return true;
255 : }
256 0 : return false;
257 : }
258 :
259 : CALLER_ATTACH BitmapGlyphInfo*
260 0 : IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::Next() {
261 0 : BitmapGlyphInfoPtr output;
262 0 : if (!HasNext()) {
263 : // Note: In C++, we do not throw exception when there's no element.
264 0 : return NULL;
265 : }
266 : output = new BitmapGlyphInfo(glyph_id_,
267 0 : container()->image_data_offset(),
268 0 : container()->GlyphStartOffset(glyph_id_),
269 0 : container()->GlyphLength(glyph_id_),
270 0 : container()->image_format());
271 0 : glyph_id_++;
272 0 : return output.Detach();
273 : }
274 :
275 : } // namespace sfntly
|