Home | History | Annotate | Download | only in bitmap
      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/bitmap/ebdt_table.h"
     18 
     19 #include <stdlib.h>
     20 
     21 #include "sfntly/table/bitmap/composite_bitmap_glyph.h"
     22 #include "sfntly/table/bitmap/simple_bitmap_glyph.h"
     23 
     24 namespace sfntly {
     25 /******************************************************************************
     26  * EbdtTable class
     27  ******************************************************************************/
     28 EbdtTable::~EbdtTable() {
     29 }
     30 
     31 int32_t EbdtTable::Version() {
     32   return data_->ReadFixed(Offset::kVersion);
     33 }
     34 
     35 CALLER_ATTACH
     36 BitmapGlyph* EbdtTable::Glyph(int32_t offset, int32_t length, int32_t format) {
     37   ReadableFontDataPtr glyph_data;
     38   glyph_data.Attach(down_cast<ReadableFontData*>(data_->Slice(offset, length)));
     39   return BitmapGlyph::CreateGlyph(glyph_data, format);
     40 }
     41 
     42 EbdtTable::EbdtTable(Header* header, ReadableFontData* data)
     43     : SubTableContainerTable(header, data) {
     44 }
     45 
     46 /******************************************************************************
     47  * EbdtTable::Builder class
     48  ******************************************************************************/
     49 EbdtTable::Builder::Builder(Header* header, WritableFontData* data)
     50   : SubTableContainerTable::Builder(header, data) {
     51 }
     52 
     53 EbdtTable::Builder::Builder(Header* header, ReadableFontData* data)
     54   : SubTableContainerTable::Builder(header, data) {
     55 }
     56 
     57 EbdtTable::Builder::~Builder() {
     58 }
     59 
     60 CALLER_ATTACH FontDataTable*
     61     EbdtTable::Builder::SubBuildTable(ReadableFontData* data) {
     62   FontDataTablePtr table = new EbdtTable(header(), data);
     63   return table.Detach();
     64 }
     65 
     66 void EbdtTable::Builder::SubDataSet() {
     67   Revert();
     68 }
     69 
     70 int32_t EbdtTable::Builder::SubDataSizeToSerialize() {
     71   if (glyph_builders_.empty()) {
     72     return 0;
     73   }
     74   bool fixed = true;
     75   int32_t size = Offset::kHeaderLength;
     76   for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
     77                                         builder_end = glyph_builders_.end();
     78                                         builder_map != builder_end;
     79                                         builder_map++) {
     80     for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
     81                                          glyph_entry_end = builder_map->end();
     82                                          glyph_entry != glyph_entry_end;
     83                                          glyph_entry++) {
     84       int32_t glyph_size = glyph_entry->second->SubDataSizeToSerialize();
     85       size += abs(glyph_size);
     86       fixed = (glyph_size <= 0) ? false : fixed;
     87     }
     88   }
     89   return (fixed ? 1 : -1) * size;
     90 }
     91 
     92 bool EbdtTable::Builder::SubReadyToSerialize() {
     93   if (glyph_builders_.empty()) {
     94     return false;
     95   }
     96   return true;
     97 }
     98 
     99 int32_t EbdtTable::Builder::SubSerialize(WritableFontData* new_data) {
    100   int32_t size = 0;
    101   size += new_data->WriteFixed(Offset::kVersion, kVersion);
    102   for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
    103                                         builder_end = glyph_builders_.end();
    104                                         builder_map != builder_end;
    105                                         builder_map++) {
    106     for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
    107                                          glyph_entry_end = builder_map->end();
    108                                          glyph_entry != glyph_entry_end;
    109                                          glyph_entry++) {
    110       WritableFontDataPtr slice;
    111       slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
    112       size += glyph_entry->second->SubSerialize(slice);
    113     }
    114   }
    115   return size;
    116 }
    117 
    118 void EbdtTable::Builder::SetLoca(BitmapLocaList* loca_list) {
    119   assert(loca_list);
    120   Revert();
    121   glyph_loca_.resize(loca_list->size());
    122   std::copy(loca_list->begin(), loca_list->end(), glyph_loca_.begin());
    123 }
    124 
    125 void EbdtTable::Builder::GenerateLocaList(BitmapLocaList* output) {
    126   assert(output);
    127   output->clear();
    128 
    129   if (glyph_builders_.empty()) {
    130     if (glyph_loca_.empty()) {
    131       return;
    132     }
    133   }
    134 
    135   int start_offset = Offset::kHeaderLength;
    136   for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
    137                                         builder_end = glyph_builders_.end();
    138                                         builder_map != builder_end;
    139                                         builder_map++) {
    140     BitmapGlyphInfoMap new_loca_map;
    141     int32_t glyph_offset = 0;
    142     for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
    143                                          glyph_end = builder_map->end();
    144                                          glyph_entry != glyph_end;
    145                                          glyph_entry++) {
    146       BitmapGlyphBuilderPtr builder = glyph_entry->second;
    147       int32_t size = builder->SubDataSizeToSerialize();
    148       BitmapGlyphInfoPtr info = new BitmapGlyphInfo(glyph_entry->first,
    149           start_offset + glyph_offset, size, builder->format());
    150       new_loca_map[glyph_entry->first] = info;
    151       glyph_offset += size;
    152     }
    153     start_offset += glyph_offset;
    154     output->push_back(new_loca_map);
    155   }
    156 }
    157 
    158 BitmapGlyphBuilderList* EbdtTable::Builder::GlyphBuilders() {
    159   return GetGlyphBuilders();
    160 }
    161 
    162 void EbdtTable::Builder::SetGlyphBuilders(
    163     BitmapGlyphBuilderList* glyph_builders) {
    164   glyph_builders_.clear();
    165   std::copy(glyph_builders->begin(), glyph_builders->end(),
    166             glyph_builders_.begin());
    167   set_model_changed();
    168 }
    169 
    170 void EbdtTable::Builder::Revert() {
    171   glyph_loca_.clear();
    172   glyph_builders_.clear();
    173   set_model_changed(false);
    174 }
    175 
    176 CALLER_ATTACH
    177 EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
    178                                                       WritableFontData* data) {
    179   Ptr<EbdtTable::Builder> builder;
    180   builder = new Builder(header, data);
    181   return builder.Detach();
    182 }
    183 
    184 CALLER_ATTACH
    185 EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
    186                                                       ReadableFontData* data) {
    187   Ptr<EbdtTable::Builder> builder;
    188   builder = new Builder(header, data);
    189   return builder.Detach();
    190 }
    191 
    192 BitmapGlyphBuilderList* EbdtTable::Builder::GetGlyphBuilders() {
    193   if (glyph_builders_.empty()) {
    194     if (glyph_loca_.empty()) {
    195 #if !defined (SFNTLY_NO_EXCEPTION)
    196       throw IllegalStateException(
    197           "Loca values not set - unable to parse glyph data.");
    198 #endif
    199       return NULL;
    200     }
    201     Initialize(InternalReadData(), &glyph_loca_, &glyph_builders_);
    202     set_model_changed();
    203   }
    204   return &glyph_builders_;
    205 }
    206 
    207 void EbdtTable::Builder::Initialize(ReadableFontData* data,
    208                                     BitmapLocaList* loca_list,
    209                                     BitmapGlyphBuilderList* output) {
    210   assert(loca_list);
    211   assert(output);
    212 
    213   output->clear();
    214   if (data) {
    215     for (BitmapLocaList::iterator loca_map = loca_list->begin(),
    216                                   loca_end = loca_list->end();
    217                                   loca_map != loca_end; loca_map++) {
    218       BitmapGlyphBuilderMap glyph_builder_map;
    219       for (BitmapGlyphInfoMap::iterator entry = loca_map->begin(),
    220                                         entry_end = loca_map->end();
    221                                         entry != entry_end; entry++) {
    222         BitmapGlyphInfoPtr info = entry->second;
    223         ReadableFontDataPtr slice;
    224         slice.Attach(down_cast<ReadableFontData*>(data->Slice(
    225             info->offset(), info->length())));
    226         BitmapGlyphBuilderPtr glyph_builder;
    227         glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
    228             slice, info->format()));
    229         glyph_builder_map[entry->first] = glyph_builder;
    230       }
    231       output->push_back(glyph_builder_map);
    232     }
    233   }
    234 }
    235 
    236 }  // namespace sfntly
    237