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 21namespace sfntly { 22 23/****************************************************************************** 24 * FontDataTable class 25 ******************************************************************************/ 26 27FontDataTable::FontDataTable(ReadableFontData* data) { 28 data_ = data; 29} 30 31FontDataTable::~FontDataTable() {} 32 33ReadableFontData* FontDataTable::ReadFontData() { 34 return data_; 35} 36 37int32_t FontDataTable::DataLength() { 38 return data_->Length(); 39} 40 41int32_t FontDataTable::Serialize(OutputStream* os) { 42 return data_->CopyTo(os); 43} 44 45int32_t FontDataTable::Serialize(WritableFontData* data) { 46 return data_->CopyTo(data); 47} 48 49/****************************************************************************** 50 * FontDataTable::Builder class 51 ******************************************************************************/ 52CALLER_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 75void FontDataTable::Builder::SetData(ReadableFontData* data) { 76 InternalSetData(data, true); 77} 78 79 80CALLER_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 108bool FontDataTable::Builder::ReadyToBuild() { 109 return true; 110} 111 112ReadableFontData* FontDataTable::Builder::InternalReadData() { 113 return (r_data_ != NULL) ? r_data_.p_ : 114 static_cast<ReadableFontData*>(w_data_.p_); 115} 116 117WritableFontData* 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 138FontDataTable::Builder::Builder() 139 : model_changed_(false), 140 contained_model_changed_(false), 141 data_changed_(false) { 142} 143 144FontDataTable::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 151FontDataTable::Builder::Builder(WritableFontData* data) 152 : model_changed_(false), 153 contained_model_changed_(false), 154 data_changed_(false) { 155 w_data_ = data; 156} 157 158FontDataTable::Builder::Builder(ReadableFontData* data) 159 : model_changed_(false), 160 contained_model_changed_(false), 161 data_changed_(false) { 162 r_data_ = data; 163} 164 165FontDataTable::Builder::~Builder() { 166} 167 168void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) { 169 // Default: NOP. 170 UNREFERENCED_PARAMETER(table); 171} 172 173void 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 183void 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