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/font_data_table.h"
18
19 #include "sfntly/data/font_output_stream.h"
20
21 namespace sfntly {
22
23 /******************************************************************************
24 * FontDataTable class
25 ******************************************************************************/
26
FontDataTable(ReadableFontData * data)27 FontDataTable::FontDataTable(ReadableFontData* data) {
28 data_ = data;
29 }
30
~FontDataTable()31 FontDataTable::~FontDataTable() {}
32
ReadFontData()33 ReadableFontData* FontDataTable::ReadFontData() {
34 return data_;
35 }
36
DataLength()37 int32_t FontDataTable::DataLength() {
38 return data_->Length();
39 }
40
Serialize(OutputStream * os)41 int32_t FontDataTable::Serialize(OutputStream* os) {
42 return data_->CopyTo(os);
43 }
44
Serialize(WritableFontData * data)45 int32_t FontDataTable::Serialize(WritableFontData* data) {
46 return data_->CopyTo(data);
47 }
48
49 /******************************************************************************
50 * FontDataTable::Builder class
51 ******************************************************************************/
Data()52 CALLER_ATTACH WritableFontData* FontDataTable::Builder::Data() {
53 WritableFontDataPtr new_data;
54 if (model_changed_) {
55 if (!SubReadyToSerialize()) {
56 #if !defined (SFNTLY_NO_EXCEPTION)
57 throw IOException("Table not ready to build.");
58 #endif
59 return NULL;
60 }
61 int32_t size = SubDataSizeToSerialize();
62 new_data.Attach(WritableFontData::CreateWritableFontData(size));
63 SubSerialize(new_data);
64 } else {
65 ReadableFontDataPtr data = InternalReadData();
66 new_data.Attach(WritableFontData::CreateWritableFontData(
67 data != NULL ? data->Length() : 0));
68 if (data != NULL) {
69 data->CopyTo(new_data);
70 }
71 }
72 return new_data.Detach();
73 }
74
SetData(ReadableFontData * data)75 void FontDataTable::Builder::SetData(ReadableFontData* data) {
76 InternalSetData(data, true);
77 }
78
79
Build()80 CALLER_ATTACH FontDataTable* FontDataTable::Builder::Build() {
81 FontDataTablePtr table; // NULL default table
82 ReadableFontDataPtr data = InternalReadData();
83 if (model_changed_) {
84 // Let subclass serialize from model.
85 if (!SubReadyToSerialize()) {
86 #if !defined (SFNTLY_NO_EXCEPTION)
87 throw IOException("Table not ready to build.");
88 #endif
89 return NULL;
90 }
91 int32_t size = SubDataSizeToSerialize();
92 WritableFontDataPtr new_data;
93 new_data.Attach(WritableFontData::CreateWritableFontData(size));
94 SubSerialize(new_data);
95 data = new_data;
96 }
97
98 if (data != NULL) {
99 table = SubBuildTable(data);
100 NotifyPostTableBuild(table);
101 }
102
103 r_data_.Release();
104 w_data_.Release();
105 return table;
106 }
107
ReadyToBuild()108 bool FontDataTable::Builder::ReadyToBuild() {
109 return true;
110 }
111
InternalReadData()112 ReadableFontData* FontDataTable::Builder::InternalReadData() {
113 return (r_data_ != NULL) ? r_data_.p_ :
114 static_cast<ReadableFontData*>(w_data_.p_);
115 }
116
InternalWriteData()117 WritableFontData* FontDataTable::Builder::InternalWriteData() {
118 if (w_data_ == NULL) {
119 WritableFontDataPtr new_data;
120 new_data.Attach(WritableFontData::CreateWritableFontData(
121 r_data_ == NULL ? 0 : r_data_->Length()));
122 #if !defined (SFNTLY_NO_EXCEPTION)
123 try {
124 #endif
125 if (r_data_) {
126 r_data_->CopyTo(new_data);
127 }
128 #if !defined (SFNTLY_NO_EXCEPTION)
129 } catch (IOException& e) {
130 // TODO(stuartg): fix when IOExceptions are cleaned up
131 }
132 #endif
133 InternalSetData(new_data, false);
134 }
135 return w_data_.p_;
136 }
137
Builder()138 FontDataTable::Builder::Builder()
139 : model_changed_(false),
140 contained_model_changed_(false),
141 data_changed_(false) {
142 }
143
Builder(int32_t data_size)144 FontDataTable::Builder::Builder(int32_t data_size)
145 : model_changed_(false),
146 contained_model_changed_(false),
147 data_changed_(false) {
148 w_data_.Attach(WritableFontData::CreateWritableFontData(data_size));
149 }
150
Builder(WritableFontData * data)151 FontDataTable::Builder::Builder(WritableFontData* data)
152 : model_changed_(false),
153 contained_model_changed_(false),
154 data_changed_(false) {
155 w_data_ = data;
156 }
157
Builder(ReadableFontData * data)158 FontDataTable::Builder::Builder(ReadableFontData* data)
159 : model_changed_(false),
160 contained_model_changed_(false),
161 data_changed_(false) {
162 r_data_ = data;
163 }
164
~Builder()165 FontDataTable::Builder::~Builder() {
166 }
167
NotifyPostTableBuild(FontDataTable * table)168 void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) {
169 // Default: NOP.
170 UNREFERENCED_PARAMETER(table);
171 }
172
InternalSetData(WritableFontData * data,bool data_changed)173 void FontDataTable::Builder::InternalSetData(WritableFontData* data,
174 bool data_changed) {
175 w_data_ = data;
176 r_data_ = NULL;
177 if (data_changed) {
178 data_changed_ = true;
179 SubDataSet();
180 }
181 }
182
InternalSetData(ReadableFontData * data,bool data_changed)183 void FontDataTable::Builder::InternalSetData(ReadableFontData* data,
184 bool data_changed) {
185 w_data_ = NULL;
186 r_data_ = data;
187 if (data_changed) {
188 data_changed_ = true;
189 SubDataSet();
190 }
191 }
192
193 } // namespace sfntly
194