Home | History | Annotate | Download | only in table
      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