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/ebdt_table.h"
18 :
19 : #include <stdlib.h>
20 :
21 : #include "sfntly/table/bitmap/composite_bitmap_glyph.h"
22 : #include "sfntly/table/bitmap/simple_bitmap_glyph.h"
23 :
24 : namespace sfntly {
25 : /******************************************************************************
26 : * EbdtTable class
27 : ******************************************************************************/
28 0 : EbdtTable::~EbdtTable() {
29 0 : }
30 :
31 0 : int32_t EbdtTable::Version() {
32 0 : return data_->ReadFixed(Offset::kVersion);
33 : }
34 :
35 : CALLER_ATTACH
36 0 : BitmapGlyph* EbdtTable::Glyph(int32_t offset, int32_t length, int32_t format) {
37 0 : ReadableFontDataPtr glyph_data;
38 0 : glyph_data.Attach(down_cast<ReadableFontData*>(data_->Slice(offset, length)));
39 0 : return BitmapGlyph::CreateGlyph(glyph_data, format);
40 : }
41 :
42 0 : EbdtTable::EbdtTable(Header* header, ReadableFontData* data)
43 0 : : SubTableContainerTable(header, data) {
44 0 : }
45 :
46 : /******************************************************************************
47 : * EbdtTable::Builder class
48 : ******************************************************************************/
49 0 : EbdtTable::Builder::Builder(Header* header, WritableFontData* data)
50 0 : : SubTableContainerTable::Builder(header, data) {
51 0 : }
52 :
53 0 : EbdtTable::Builder::Builder(Header* header, ReadableFontData* data)
54 0 : : SubTableContainerTable::Builder(header, data) {
55 0 : }
56 :
57 0 : EbdtTable::Builder::~Builder() {
58 0 : }
59 :
60 : CALLER_ATTACH FontDataTable*
61 0 : EbdtTable::Builder::SubBuildTable(ReadableFontData* data) {
62 0 : FontDataTablePtr table = new EbdtTable(header(), data);
63 0 : return table.Detach();
64 : }
65 :
66 0 : void EbdtTable::Builder::SubDataSet() {
67 0 : Revert();
68 0 : }
69 :
70 0 : int32_t EbdtTable::Builder::SubDataSizeToSerialize() {
71 0 : if (glyph_builders_.empty()) {
72 0 : return 0;
73 : }
74 0 : bool fixed = true;
75 0 : int32_t size = Offset::kHeaderLength;
76 0 : for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
77 0 : builder_end = glyph_builders_.end();
78 : builder_map != builder_end;
79 : builder_map++) {
80 0 : for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
81 0 : glyph_entry_end = builder_map->end();
82 : glyph_entry != glyph_entry_end;
83 : glyph_entry++) {
84 0 : int32_t glyph_size = glyph_entry->second->SubDataSizeToSerialize();
85 0 : size += abs(glyph_size);
86 0 : fixed = (glyph_size <= 0) ? false : fixed;
87 : }
88 : }
89 0 : return (fixed ? 1 : -1) * size;
90 : }
91 :
92 0 : bool EbdtTable::Builder::SubReadyToSerialize() {
93 0 : if (glyph_builders_.empty()) {
94 0 : return false;
95 : }
96 0 : return true;
97 : }
98 :
99 0 : int32_t EbdtTable::Builder::SubSerialize(WritableFontData* new_data) {
100 0 : int32_t size = 0;
101 0 : size += new_data->WriteFixed(Offset::kVersion, kVersion);
102 0 : for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
103 0 : builder_end = glyph_builders_.end();
104 : builder_map != builder_end;
105 : builder_map++) {
106 0 : for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
107 0 : glyph_entry_end = builder_map->end();
108 : glyph_entry != glyph_entry_end;
109 : glyph_entry++) {
110 0 : WritableFontDataPtr slice;
111 0 : slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
112 0 : size += glyph_entry->second->SubSerialize(slice);
113 : }
114 : }
115 0 : return size;
116 : }
117 :
118 0 : void EbdtTable::Builder::SetLoca(BitmapLocaList* loca_list) {
119 0 : assert(loca_list);
120 0 : Revert();
121 0 : glyph_loca_.resize(loca_list->size());
122 0 : std::copy(loca_list->begin(), loca_list->end(), glyph_loca_.begin());
123 0 : }
124 :
125 0 : void EbdtTable::Builder::GenerateLocaList(BitmapLocaList* output) {
126 0 : assert(output);
127 0 : output->clear();
128 :
129 0 : if (glyph_builders_.empty()) {
130 0 : if (glyph_loca_.empty()) {
131 0 : return;
132 : }
133 : }
134 :
135 0 : int start_offset = Offset::kHeaderLength;
136 0 : for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
137 0 : builder_end = glyph_builders_.end();
138 : builder_map != builder_end;
139 : builder_map++) {
140 0 : BitmapGlyphInfoMap new_loca_map;
141 0 : int32_t glyph_offset = 0;
142 0 : for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
143 0 : glyph_end = builder_map->end();
144 : glyph_entry != glyph_end;
145 : glyph_entry++) {
146 0 : BitmapGlyphBuilderPtr builder = glyph_entry->second;
147 0 : int32_t size = builder->SubDataSizeToSerialize();
148 0 : BitmapGlyphInfoPtr info = new BitmapGlyphInfo(glyph_entry->first,
149 0 : start_offset + glyph_offset, size, builder->format());
150 0 : new_loca_map[glyph_entry->first] = info;
151 0 : glyph_offset += size;
152 : }
153 0 : start_offset += glyph_offset;
154 0 : output->push_back(new_loca_map);
155 : }
156 : }
157 :
158 0 : BitmapGlyphBuilderList* EbdtTable::Builder::GlyphBuilders() {
159 0 : return GetGlyphBuilders();
160 : }
161 :
162 0 : void EbdtTable::Builder::SetGlyphBuilders(
163 : BitmapGlyphBuilderList* glyph_builders) {
164 0 : glyph_builders_.clear();
165 : std::copy(glyph_builders->begin(), glyph_builders->end(),
166 0 : glyph_builders_.begin());
167 0 : set_model_changed();
168 0 : }
169 :
170 0 : void EbdtTable::Builder::Revert() {
171 0 : glyph_loca_.clear();
172 0 : glyph_builders_.clear();
173 0 : set_model_changed(false);
174 0 : }
175 :
176 : CALLER_ATTACH
177 0 : EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
178 : WritableFontData* data) {
179 0 : Ptr<EbdtTable::Builder> builder;
180 0 : builder = new Builder(header, data);
181 0 : return builder.Detach();
182 : }
183 :
184 : CALLER_ATTACH
185 0 : EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
186 : ReadableFontData* data) {
187 0 : Ptr<EbdtTable::Builder> builder;
188 0 : builder = new Builder(header, data);
189 0 : return builder.Detach();
190 : }
191 :
192 0 : BitmapGlyphBuilderList* EbdtTable::Builder::GetGlyphBuilders() {
193 0 : if (glyph_builders_.empty()) {
194 0 : if (glyph_loca_.empty()) {
195 : #if !defined (SFNTLY_NO_EXCEPTION)
196 : throw IllegalStateException(
197 : "Loca values not set - unable to parse glyph data.");
198 : #endif
199 0 : return NULL;
200 : }
201 0 : Initialize(InternalReadData(), &glyph_loca_, &glyph_builders_);
202 0 : set_model_changed();
203 : }
204 0 : return &glyph_builders_;
205 : }
206 :
207 0 : void EbdtTable::Builder::Initialize(ReadableFontData* data,
208 : BitmapLocaList* loca_list,
209 : BitmapGlyphBuilderList* output) {
210 0 : assert(loca_list);
211 0 : assert(output);
212 :
213 0 : output->clear();
214 0 : if (data) {
215 0 : for (BitmapLocaList::iterator loca_map = loca_list->begin(),
216 0 : loca_end = loca_list->end();
217 : loca_map != loca_end; loca_map++) {
218 0 : BitmapGlyphBuilderMap glyph_builder_map;
219 0 : for (BitmapGlyphInfoMap::iterator entry = loca_map->begin(),
220 0 : entry_end = loca_map->end();
221 : entry != entry_end; entry++) {
222 0 : BitmapGlyphInfoPtr info = entry->second;
223 0 : ReadableFontDataPtr slice;
224 0 : slice.Attach(down_cast<ReadableFontData*>(data->Slice(
225 0 : info->offset(), info->length())));
226 0 : BitmapGlyphBuilderPtr glyph_builder;
227 0 : glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
228 0 : slice, info->format()));
229 0 : glyph_builder_map[entry->first] = glyph_builder;
230 : }
231 0 : output->push_back(glyph_builder_map);
232 : }
233 : }
234 0 : }
235 :
236 : } // namespace sfntly
|