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/truetype/loca_table.h"
18 : #include "sfntly/port/exception_type.h"
19 :
20 : namespace sfntly {
21 : /******************************************************************************
22 : * LocaTable class
23 : ******************************************************************************/
24 0 : LocaTable::~LocaTable() {}
25 :
26 0 : int32_t LocaTable::GlyphOffset(int32_t glyph_id) {
27 0 : if (glyph_id < 0 || glyph_id >= num_glyphs_) {
28 : #if !defined (SFNTLY_NO_EXCEPTION)
29 : throw IndexOutOfBoundException("Glyph ID is out of bounds.");
30 : #endif
31 0 : return 0;
32 : }
33 0 : return Loca(glyph_id);
34 : }
35 :
36 0 : int32_t LocaTable::GlyphLength(int32_t glyph_id) {
37 0 : if (glyph_id < 0 || glyph_id >= num_glyphs_) {
38 : #if !defined (SFNTLY_NO_EXCEPTION)
39 : throw IndexOutOfBoundException("Glyph ID is out of bounds.");
40 : #endif
41 0 : return 0;
42 : }
43 0 : return Loca(glyph_id + 1) - Loca(glyph_id);
44 : }
45 :
46 0 : int32_t LocaTable::NumLocas() {
47 0 : return num_glyphs_ + 1;
48 : }
49 :
50 0 : int32_t LocaTable::Loca(int32_t index) {
51 0 : if (index > num_glyphs_) {
52 : #if !defined (SFNTLY_NO_EXCEPTION)
53 : throw IndexOutOfBoundException();
54 : #endif
55 0 : return 0;
56 : }
57 0 : if (format_version_ == IndexToLocFormat::kShortOffset) {
58 0 : return 2 * data_->ReadUShort(index * DataSize::kUSHORT);
59 : }
60 0 : return data_->ReadULongAsInt(index * DataSize::kULONG);
61 : }
62 :
63 0 : LocaTable::LocaTable(Header* header,
64 : ReadableFontData* data,
65 : int32_t format_version,
66 0 : int32_t num_glyphs)
67 : : Table(header, data),
68 : format_version_(format_version),
69 0 : num_glyphs_(num_glyphs) {
70 0 : }
71 :
72 : /******************************************************************************
73 : * LocaTable::Iterator class
74 : ******************************************************************************/
75 0 : LocaTable::LocaIterator::LocaIterator(LocaTable* table)
76 0 : : PODIterator<int32_t, LocaTable>(table), index_(-1) {
77 0 : }
78 :
79 0 : bool LocaTable::LocaIterator::HasNext() {
80 0 : return index_ <= container()->num_glyphs_;
81 : }
82 :
83 0 : int32_t LocaTable::LocaIterator::Next() {
84 0 : return container()->Loca(index_++);
85 : }
86 :
87 : /******************************************************************************
88 : * LocaTable::Builder class
89 : ******************************************************************************/
90 0 : LocaTable::Builder::Builder(Header* header, WritableFontData* data)
91 : : Table::Builder(header, data),
92 : format_version_(IndexToLocFormat::kLongOffset),
93 0 : num_glyphs_(-1) {
94 0 : }
95 :
96 0 : LocaTable::Builder::Builder(Header* header, ReadableFontData* data)
97 : : Table::Builder(header, data),
98 : format_version_(IndexToLocFormat::kLongOffset),
99 0 : num_glyphs_(-1) {
100 0 : }
101 :
102 0 : LocaTable::Builder::~Builder() {}
103 :
104 : CALLER_ATTACH
105 0 : LocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header,
106 : WritableFontData* data) {
107 0 : Ptr<LocaTable::Builder> builder;
108 0 : builder = new LocaTable::Builder(header, data);
109 0 : return builder.Detach();
110 : }
111 :
112 0 : IntegerList* LocaTable::Builder::LocaList() {
113 0 : return GetLocaList();
114 : }
115 :
116 0 : void LocaTable::Builder::SetLocaList(IntegerList* list) {
117 0 : loca_.clear();
118 0 : if (list) {
119 0 : loca_ = *list;
120 0 : set_model_changed();
121 : }
122 0 : }
123 :
124 0 : int32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) {
125 0 : if (CheckGlyphRange(glyph_id) == -1) {
126 0 : return 0;
127 : }
128 0 : return GetLocaList()->at(glyph_id);
129 : }
130 :
131 0 : int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) {
132 0 : if (CheckGlyphRange(glyph_id) == -1) {
133 0 : return 0;
134 : }
135 0 : return GetLocaList()->at(glyph_id + 1) - GetLocaList()->at(glyph_id);
136 : }
137 :
138 0 : void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
139 0 : num_glyphs_ = num_glyphs;
140 0 : }
141 :
142 0 : int32_t LocaTable::Builder::NumGlyphs() {
143 0 : return LastGlyphIndex() - 1;
144 : }
145 :
146 0 : void LocaTable::Builder::Revert() {
147 0 : loca_.clear();
148 0 : set_model_changed(false);
149 0 : }
150 :
151 0 : int32_t LocaTable::Builder::NumLocas() {
152 0 : return GetLocaList()->size();
153 : }
154 :
155 0 : int32_t LocaTable::Builder::Loca(int32_t index) {
156 0 : return GetLocaList()->at(index);
157 : }
158 :
159 : CALLER_ATTACH
160 0 : FontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) {
161 : FontDataTablePtr table =
162 0 : new LocaTable(header(), data, format_version_, num_glyphs_);
163 0 : return table.Detach();
164 : }
165 :
166 0 : void LocaTable::Builder::SubDataSet() {
167 0 : Initialize(InternalReadData());
168 0 : }
169 :
170 0 : int32_t LocaTable::Builder::SubDataSizeToSerialize() {
171 0 : if (loca_.empty()) {
172 0 : return 0;
173 : }
174 0 : if (format_version_ == IndexToLocFormat::kLongOffset) {
175 0 : return loca_.size() * DataSize::kULONG;
176 : }
177 0 : return loca_.size() * DataSize::kUSHORT;
178 : }
179 :
180 0 : bool LocaTable::Builder::SubReadyToSerialize() {
181 0 : return !loca_.empty();
182 : }
183 :
184 0 : int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) {
185 0 : int32_t size = 0;
186 0 : for (IntegerList::iterator l = loca_.begin(), end = loca_.end();
187 : l != end; ++l) {
188 0 : if (format_version_ == IndexToLocFormat::kLongOffset) {
189 0 : size += new_data->WriteULong(size, *l);
190 : } else {
191 0 : size += new_data->WriteUShort(size, *l / 2);
192 : }
193 : }
194 0 : num_glyphs_ = loca_.size() - 1;
195 0 : return size;
196 : }
197 :
198 0 : void LocaTable::Builder::Initialize(ReadableFontData* data) {
199 0 : ClearLoca(false);
200 0 : if (data) {
201 0 : if (NumGlyphs() < 0) {
202 : #if !defined (SFNTLY_NO_EXCEPTION)
203 : throw IllegalStateException("numglyphs not set on LocaTable Builder.");
204 : #endif
205 0 : return;
206 : }
207 : LocaTablePtr table =
208 0 : new LocaTable(header(), data, format_version_, num_glyphs_);
209 : Ptr<LocaTable::LocaIterator> loca_iter =
210 0 : new LocaTable::LocaIterator(table);
211 0 : while (loca_iter->HasNext()) {
212 0 : loca_.push_back(loca_iter->Next());
213 : }
214 : }
215 : }
216 :
217 0 : int32_t LocaTable::Builder::CheckGlyphRange(int32_t glyph_id) {
218 0 : if (glyph_id < 0 || glyph_id > LastGlyphIndex()) {
219 : #if !defined (SFNTLY_NO_EXCEPTION)
220 : throw IndexOutOfBoundsException("Glyph ID is outside of the allowed range");
221 : #endif
222 0 : return -1;
223 : }
224 0 : return glyph_id;
225 : }
226 :
227 0 : int32_t LocaTable::Builder::LastGlyphIndex() {
228 0 : return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1;
229 : }
230 :
231 0 : IntegerList* LocaTable::Builder::GetLocaList() {
232 0 : if (loca_.empty()) {
233 0 : Initialize(InternalReadData());
234 0 : set_model_changed();
235 : }
236 0 : return &loca_;
237 : }
238 :
239 0 : void LocaTable::Builder::ClearLoca(bool nullify) {
240 : // Note: in C++ port, nullify is not used at all.
241 : UNREFERENCED_PARAMETER(nullify);
242 0 : loca_.clear();
243 0 : set_model_changed(false);
244 0 : }
245 :
246 : } // namespace sfntly
|