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 FontDataTable::FontDataTable(ReadableFontData* data) { 28 data_ = data; 29 } 30 31 FontDataTable::~FontDataTable() {} 32 33 ReadableFontData* FontDataTable::ReadFontData() { 34 return data_; 35 } 36 37 int32_t FontDataTable::DataLength() { 38 return data_->Length(); 39 } 40 41 int32_t FontDataTable::Serialize(OutputStream* os) { 42 return data_->CopyTo(os); 43 } 44 45 int32_t FontDataTable::Serialize(WritableFontData* data) { 46 return data_->CopyTo(data); 47 } 48 49 /****************************************************************************** 50 * FontDataTable::Builder class 51 ******************************************************************************/ 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 75 void FontDataTable::Builder::SetData(ReadableFontData* data) { 76 InternalSetData(data, true); 77 } 78 79 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 108 bool FontDataTable::Builder::ReadyToBuild() { 109 return true; 110 } 111 112 ReadableFontData* FontDataTable::Builder::InternalReadData() { 113 return (r_data_ != NULL) ? r_data_.p_ : 114 static_cast<ReadableFontData*>(w_data_.p_); 115 } 116 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 138 FontDataTable::Builder::Builder() 139 : model_changed_(false), 140 contained_model_changed_(false), 141 data_changed_(false) { 142 } 143 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 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 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 165 FontDataTable::Builder::~Builder() { 166 } 167 168 void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) { 169 // Default: NOP. 170 UNREFERENCED_PARAMETER(table); 171 } 172 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 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