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