table.cc revision 6a2a8e7db878d1115d600c3be02e2700d8b372bc
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/table.h"
18
19#include "sfntly/font.h"
20#include "sfntly/tag.h"
21#include "sfntly/table/core/cmap_table.h"
22#include "sfntly/table/core/font_header_table.h"
23#include "sfntly/table/core/horizontal_header_table.h"
24#include "sfntly/table/core/horizontal_metrics_table.h"
25#include "sfntly/table/core/maximum_profile_table.h"
26#include "sfntly/table/core/name_table.h"
27#include "sfntly/table/core/os2_table.h"
28#include "sfntly/table/truetype/glyph_table.h"
29#include "sfntly/table/truetype/loca_table.h"
30
31namespace sfntly {
32
33/******************************************************************************
34 * Table class
35 ******************************************************************************/
36Table::~Table() {}
37
38int64_t Table::CalculatedChecksum() {
39  return data_->Checksum();
40}
41
42void Table::SetFont(Font* font) {
43  font_ = font;
44}
45
46Table::Table(Header* header, ReadableFontData* data)
47    : FontDataTable(data) {
48  header_ = header;
49}
50
51/******************************************************************************
52 * Table::Header class
53 ******************************************************************************/
54Table::Header::Header(int32_t tag)
55    : tag_(tag),
56      offset_(0),
57      offset_valid_(false),
58      length_(0),
59      length_valid_(false),
60      checksum_(0),
61      checksum_valid_(false) {
62}
63
64Table::Header::Header(int32_t tag, int32_t length)
65    : tag_(tag),
66      offset_(0),
67      offset_valid_(false),
68      length_(length),
69      length_valid_(true),
70      checksum_(0),
71      checksum_valid_(false) {
72}
73
74Table::Header::Header(int32_t tag,
75                      int64_t checksum,
76                      int32_t offset,
77                      int32_t length)
78    : tag_(tag),
79      offset_(offset),
80      offset_valid_(true),
81      length_(length),
82      length_valid_(true),
83      checksum_(checksum),
84      checksum_valid_(true) {
85}
86
87Table::Header::~Header() {}
88
89bool HeaderComparatorByOffset::operator() (const TableHeaderPtr lhs,
90                                           const TableHeaderPtr rhs) {
91  return lhs->offset_ > rhs->offset_;
92}
93
94bool HeaderComparatorByTag::operator() (const TableHeaderPtr lhs,
95                                        const TableHeaderPtr rhs) {
96  return lhs->tag_ > rhs->tag_;
97}
98
99/******************************************************************************
100 * Table::Builder class
101 ******************************************************************************/
102Table::Builder::~Builder() {
103  header_.Release();
104}
105
106void Table::Builder::NotifyPostTableBuild(FontDataTable* table) {
107  if (model_changed() || data_changed()) {
108    Table* derived_table = down_cast<Table*>(table);
109    derived_table->header_ = new Header(header()->tag(),
110                                        derived_table->DataLength());
111  }
112}
113
114CALLER_ATTACH
115Table::Builder* Table::Builder::GetBuilder(Header* header,
116                                           WritableFontData* table_data) {
117  int32_t tag = header->tag();
118  Table::Builder* builder_raw = NULL;
119
120  // Note: Tables are commented out when they are not used/ported.
121  // TODO(arthurhsu): IMPLEMENT: finish tables that are not ported.
122  /*if (tag == Tag::cmap) {
123    builder_raw = static_cast<Table::Builder*>(
124        CMapTable::CreateBuilder(font_builder, header, table_data));
125  } else*/ if (tag == Tag::head) {
126    builder_raw = static_cast<Table::Builder*>(
127        FontHeaderTable::Builder::CreateBuilder(header, table_data));
128  } else if (tag == Tag::hhea) {
129    builder_raw = static_cast<Table::Builder*>(
130        HorizontalHeaderTable::Builder::CreateBuilder(header, table_data));
131  } else if (tag == Tag::hmtx) {
132    builder_raw = static_cast<Table::Builder*>(
133        HorizontalMetricsTable::Builder::CreateBuilder(header, table_data));
134  } else if (tag == Tag::maxp) {
135    builder_raw = static_cast<Table::Builder*>(
136        MaximumProfileTable::Builder::CreateBuilder(header, table_data));
137  } else if (tag == Tag::name) {
138    builder_raw = static_cast<Table::Builder*>(
139        NameTable::Builder::CreateBuilder(header, table_data));
140  } else if (tag == Tag::OS_2) {
141    builder_raw = static_cast<Table::Builder*>(
142        OS2Table::Builder::CreateBuilder(header, table_data));
143  }/* else if (tag == Tag::PostScript) {
144    builder_raw = static_cast<Table::Builder*>(
145        PostScriptTable::Builder::CreateBuilder(header, table_data));
146  } else if (tag == Tag::cvt) {
147    builder_raw = static_cast<Table::Builder*>(
148        ControlValueTable::Builder::CreateBuilder(header, table_data));
149  }*/ else if (tag == Tag::glyf) {
150    builder_raw = static_cast<Table::Builder*>(
151        GlyphTable::Builder::CreateBuilder(header, table_data));
152  } else if (tag == Tag::loca) {
153    builder_raw = static_cast<Table::Builder*>(
154        LocaTable::Builder::CreateBuilder(header, table_data));
155  }/* else if (tag == Tag::prep) {
156    builder_raw = static_cast<Table::Builder*>(
157        ControlProgramTable::Builder::CreateBuilder(header, table_data));
158  }*/ else if (tag == Tag::bhed) {
159    builder_raw = static_cast<Table::Builder*>(
160        FontHeaderTable::Builder::CreateBuilder(header, table_data));
161  } else {
162    builder_raw = static_cast<Table::Builder*>(
163        Table::GenericTableBuilder::CreateBuilder(header, table_data));
164  }
165
166  return builder_raw;
167}
168
169Table::Builder::Builder(Header* header, WritableFontData* data)
170    : FontDataTable::Builder(data) {
171  header_ = header;
172}
173
174Table::Builder::Builder(Header* header, ReadableFontData* data)
175    : FontDataTable::Builder(data) {
176  header_ = header;
177}
178
179Table::Builder::Builder(Header* header) {
180  header_ = header;
181}
182
183/******************************************************************************
184 * Table::TableBasedTableBuilder class
185 ******************************************************************************/
186Table::TableBasedTableBuilder::~TableBasedTableBuilder() {}
187
188int32_t Table::TableBasedTableBuilder::SubSerialize(WritableFontData* data) {
189  UNREFERENCED_PARAMETER(data);
190  return 0;
191}
192
193bool Table::TableBasedTableBuilder::SubReadyToSerialize() {
194  return false;
195}
196
197int32_t Table::TableBasedTableBuilder::SubDataSizeToSerialize() {
198  return 0;
199}
200
201void Table::TableBasedTableBuilder::SubDataSet() {
202  table_ = NULL;
203}
204
205CALLER_ATTACH FontDataTable* Table::TableBasedTableBuilder::Build() {
206  FontDataTablePtr table = static_cast<FontDataTable*>(GetTable());
207  return table.Detach();
208}
209
210Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
211                                                      WritableFontData* data)
212    : Builder(header, data) {
213}
214
215Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
216                                                      ReadableFontData* data)
217    : Builder(header, data) {
218}
219
220Table::TableBasedTableBuilder::TableBasedTableBuilder(Header* header)
221    : Builder(header) {
222}
223
224Table* Table::TableBasedTableBuilder::GetTable() {
225  if (table_ == NULL) {
226    table_.Attach(down_cast<Table*>(SubBuildTable(InternalReadData())));
227  }
228  return table_;
229}
230
231/******************************************************************************
232 * Table::GenericTableBuilder class
233 ******************************************************************************/
234Table::GenericTableBuilder::GenericTableBuilder(Header* header,
235                                                WritableFontData* data)
236    : TableBasedTableBuilder(header, data) {
237}
238
239CALLER_ATTACH FontDataTable*
240    Table::GenericTableBuilder::SubBuildTable(ReadableFontData* data) {
241  // Note: In C++ port, we use GenericTable, the ref-counted version of Table
242  UNREFERENCED_PARAMETER(data);
243  FontDataTablePtr table = new GenericTable(this->header(), InternalReadData());
244  return table.Detach();
245}
246
247CALLER_ATTACH Table::GenericTableBuilder*
248    Table::GenericTableBuilder::CreateBuilder(Header* header,
249                                              WritableFontData* data) {
250  Ptr<Table::GenericTableBuilder> builder =
251      new Table::GenericTableBuilder(header, data);
252  return builder.Detach();
253}
254
255}  // namespace sfntly
256