LCOV - code coverage report
Current view: top level - gfx/sfntly/cpp/src/sfntly/table/bitmap - index_sub_table_format4.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 204 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 45 0.0 %
Legend: Lines: hit not hit

          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/bitmap/index_sub_table_format4.h"
      18             : 
      19             : #include "sfntly/table/bitmap/eblc_table.h"
      20             : 
      21             : namespace sfntly {
      22             : /******************************************************************************
      23             :  * IndexSubTableFormat4 class
      24             :  ******************************************************************************/
      25           0 : IndexSubTableFormat4::~IndexSubTableFormat4() {
      26           0 : }
      27             : 
      28           0 : int32_t IndexSubTableFormat4::NumGlyphs() {
      29           0 :   return IndexSubTableFormat4::NumGlyphs(data_, 0);
      30             : }
      31             : 
      32           0 : int32_t IndexSubTableFormat4::GlyphStartOffset(int32_t glyph_id) {
      33           0 :   int32_t loca = CheckGlyphRange(glyph_id);
      34           0 :   if (loca == -1) {
      35           0 :     return -1;
      36             :   }
      37           0 :   int32_t pair_index = FindCodeOffsetPair(glyph_id);
      38           0 :   if (pair_index < 0) {
      39           0 :     return -1;
      40             :   }
      41           0 :   return data_->ReadUShort(EblcTable::Offset::kIndexSubTable4_glyphArray +
      42             :                            pair_index *
      43             :                            EblcTable::Offset::kCodeOffsetPairLength +
      44           0 :                            EblcTable::Offset::kCodeOffsetPair_offset);
      45             : }
      46             : 
      47           0 : int32_t IndexSubTableFormat4::GlyphLength(int32_t glyph_id) {
      48           0 :   int32_t loca = CheckGlyphRange(glyph_id);
      49           0 :   if (loca == -1) {
      50           0 :     return -1;
      51             :   }
      52             : 
      53           0 :   int32_t pair_index = FindCodeOffsetPair(glyph_id);
      54           0 :   if (pair_index < 0) {
      55           0 :     return -1;
      56             :   }
      57           0 :   return data_->ReadUShort(
      58           0 :              EblcTable::Offset::kIndexSubTable4_glyphArray +
      59             :              (pair_index + 1) * EblcTable::Offset::kCodeOffsetPairLength +
      60           0 :              EblcTable::Offset::kCodeOffsetPair_offset) -
      61           0 :          data_->ReadUShort(
      62           0 :              EblcTable::Offset::kIndexSubTable4_glyphArray +
      63             :              (pair_index) * EblcTable::Offset::kCodeOffsetPairLength +
      64           0 :              EblcTable::Offset::kCodeOffsetPair_offset);
      65             : }
      66             : 
      67           0 : IndexSubTableFormat4::IndexSubTableFormat4(ReadableFontData* data,
      68             :                                            int32_t first,
      69           0 :                                            int32_t last)
      70           0 :     : IndexSubTable(data, first, last) {
      71           0 : }
      72             : 
      73           0 : int32_t IndexSubTableFormat4::FindCodeOffsetPair(int32_t glyph_id) {
      74           0 :   return data_->SearchUShort(EblcTable::Offset::kIndexSubTable4_glyphArray,
      75             :                              EblcTable::Offset::kCodeOffsetPairLength,
      76           0 :                              NumGlyphs(),
      77           0 :                              glyph_id);
      78             : }
      79             : 
      80           0 : int32_t IndexSubTableFormat4::NumGlyphs(ReadableFontData* data,
      81             :                                         int32_t table_offset) {
      82           0 :   int32_t num_glyphs = data->ReadULongAsInt(table_offset +
      83           0 :       EblcTable::Offset::kIndexSubTable4_numGlyphs);
      84           0 :   return num_glyphs;
      85             : }
      86             : 
      87             : /******************************************************************************
      88             :  * IndexSubTableFormat4::CodeOffsetPair related class
      89             :  ******************************************************************************/
      90           0 : IndexSubTableFormat4::CodeOffsetPair::CodeOffsetPair(int32_t glyph_code,
      91           0 :                                                      int32_t offset)
      92           0 :     : glyph_code_(glyph_code), offset_(offset) {
      93           0 : }
      94             : 
      95           0 : IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder()
      96           0 :     : CodeOffsetPair(0, 0) {
      97           0 : }
      98             : 
      99           0 : IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder(
     100           0 :     int32_t glyph_code, int32_t offset)
     101           0 :     : CodeOffsetPair(glyph_code, offset) {
     102           0 : }
     103             : 
     104           0 : bool IndexSubTableFormat4::CodeOffsetPairGlyphCodeComparator::operator()(
     105             :     const CodeOffsetPair& lhs, const CodeOffsetPair& rhs) {
     106           0 :   return lhs.glyph_code() < rhs.glyph_code();
     107             : }
     108             : 
     109             : /******************************************************************************
     110             :  * IndexSubTableFormat4::Builder class
     111             :  ******************************************************************************/
     112           0 : IndexSubTableFormat4::Builder::~Builder() {
     113           0 : }
     114             : 
     115           0 : int32_t IndexSubTableFormat4::Builder::NumGlyphs() {
     116           0 :   return GetOffsetArray()->size() - 1;
     117             : }
     118             : 
     119           0 : int32_t IndexSubTableFormat4::Builder::GlyphLength(int32_t glyph_id) {
     120           0 :   int32_t loca = CheckGlyphRange(glyph_id);
     121           0 :   if (loca == -1) {
     122           0 :     return 0;
     123             :   }
     124           0 :   int32_t pair_index = FindCodeOffsetPair(glyph_id);
     125           0 :   if (pair_index == -1) {
     126           0 :     return 0;
     127             :   }
     128           0 :   return GetOffsetArray()->at(pair_index + 1).offset() -
     129           0 :          GetOffsetArray()->at(pair_index).offset();
     130             : }
     131             : 
     132           0 : int32_t IndexSubTableFormat4::Builder::GlyphStartOffset(int32_t glyph_id) {
     133           0 :   int32_t loca = CheckGlyphRange(glyph_id);
     134           0 :   if (loca == -1) {
     135           0 :     return -1;
     136             :   }
     137           0 :   int32_t pair_index = FindCodeOffsetPair(glyph_id);
     138           0 :   if (pair_index == -1) {
     139           0 :     return -1;
     140             :   }
     141           0 :   return GetOffsetArray()->at(pair_index).offset();
     142             : }
     143             : 
     144             : CALLER_ATTACH IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*
     145           0 :     IndexSubTableFormat4::Builder::GetIterator() {
     146             :   Ptr<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator> it =
     147           0 :       new IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator(this);
     148           0 :   return it.Detach();
     149             : }
     150             : 
     151             : // static
     152             : CALLER_ATTACH IndexSubTableFormat4::Builder*
     153           0 : IndexSubTableFormat4::Builder::CreateBuilder() {
     154           0 :   IndexSubTableFormat4BuilderPtr output = new IndexSubTableFormat4::Builder();
     155           0 :   return output.Detach();
     156             : }
     157             : 
     158             : // static
     159             : CALLER_ATTACH IndexSubTableFormat4::Builder*
     160           0 : IndexSubTableFormat4::Builder::CreateBuilder(ReadableFontData* data,
     161             :                                              int32_t index_sub_table_offset,
     162             :                                              int32_t first_glyph_index,
     163             :                                              int32_t last_glyph_index) {
     164             :   int32_t length = Builder::DataLength(data,
     165             :                                        index_sub_table_offset,
     166             :                                        first_glyph_index,
     167           0 :                                        last_glyph_index);
     168           0 :   ReadableFontDataPtr new_data;
     169           0 :   new_data.Attach(down_cast<ReadableFontData*>(
     170           0 :       data->Slice(index_sub_table_offset, length)));
     171           0 :   if (new_data == NULL) {
     172           0 :     return NULL;
     173             :   }
     174             :   IndexSubTableFormat4BuilderPtr output =
     175             :       new IndexSubTableFormat4::Builder(new_data,
     176             :                                         first_glyph_index,
     177           0 :                                         last_glyph_index);
     178           0 :   return output.Detach();
     179             : }
     180             : 
     181             : // static
     182             : CALLER_ATTACH IndexSubTableFormat4::Builder*
     183           0 : IndexSubTableFormat4::Builder::CreateBuilder(WritableFontData* data,
     184             :                                              int32_t index_sub_table_offset,
     185             :                                              int32_t first_glyph_index,
     186             :                                              int32_t last_glyph_index) {
     187             :   int32_t length = Builder::DataLength(data,
     188             :                                        index_sub_table_offset,
     189             :                                        first_glyph_index,
     190           0 :                                        last_glyph_index);
     191           0 :   WritableFontDataPtr new_data;
     192           0 :   new_data.Attach(down_cast<WritableFontData*>(
     193           0 :       data->Slice(index_sub_table_offset, length)));
     194             :   IndexSubTableFormat4BuilderPtr output =
     195             :       new IndexSubTableFormat4::Builder(new_data,
     196             :                                         first_glyph_index,
     197           0 :                                         last_glyph_index);
     198           0 :   return output.Detach();
     199             : }
     200             : 
     201           0 : CALLER_ATTACH FontDataTable* IndexSubTableFormat4::Builder::SubBuildTable(
     202             :     ReadableFontData* data) {
     203             :   IndexSubTableFormat4Ptr output = new IndexSubTableFormat4(
     204           0 :       data, first_glyph_index(), last_glyph_index());
     205           0 :   return output.Detach();
     206             : }
     207             : 
     208           0 : void IndexSubTableFormat4::Builder::SubDataSet() {
     209           0 :   Revert();
     210           0 : }
     211             : 
     212           0 : int32_t IndexSubTableFormat4::Builder::SubDataSizeToSerialize() {
     213           0 :   if (offset_pair_array_.empty()) {
     214           0 :     return InternalReadData()->Length();
     215             :   }
     216             :   return EblcTable::Offset::kIndexSubHeaderLength + DataSize::kULONG +
     217           0 :          GetOffsetArray()->size() *
     218           0 :          EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
     219             : }
     220             : 
     221           0 : bool IndexSubTableFormat4::Builder::SubReadyToSerialize() {
     222           0 :   if (!offset_pair_array_.empty()) {
     223           0 :     return true;
     224             :   }
     225           0 :   return false;
     226             : }
     227             : 
     228           0 : int32_t IndexSubTableFormat4::Builder::SubSerialize(
     229             :     WritableFontData* new_data) {
     230           0 :   int32_t size = SerializeIndexSubHeader(new_data);
     231           0 :   if (!model_changed()) {
     232           0 :     if (InternalReadData() == NULL) {
     233           0 :       return size;
     234             :     }
     235           0 :     ReadableFontDataPtr source;
     236           0 :     WritableFontDataPtr target;
     237           0 :     source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
     238           0 :         EblcTable::Offset::kIndexSubTable4_glyphArray)));
     239           0 :     target.Attach(down_cast<WritableFontData*>(new_data->Slice(
     240           0 :         EblcTable::Offset::kIndexSubTable4_glyphArray)));
     241           0 :     size += source->CopyTo(target);
     242             :   } else {
     243           0 :     size += new_data->WriteLong(size, offset_pair_array_.size() - 1);
     244           0 :     for (std::vector<CodeOffsetPairBuilder>::iterator
     245           0 :              b = GetOffsetArray()->begin(), e = GetOffsetArray()->end();
     246             :              b != e; b++) {
     247           0 :       size += new_data->WriteUShort(size, b->glyph_code());
     248           0 :       size += new_data->WriteUShort(size, b->offset());
     249             :     }
     250             :   }
     251           0 :   return size;
     252             : }
     253             : 
     254           0 : void IndexSubTableFormat4::Builder::Revert() {
     255           0 :   offset_pair_array_.clear();
     256           0 :   IndexSubTable::Builder::Revert();
     257           0 : }
     258             : 
     259           0 : void IndexSubTableFormat4::Builder::SetOffsetArray(
     260             :     const std::vector<CodeOffsetPairBuilder>& pair_array) {
     261           0 :   offset_pair_array_.clear();
     262           0 :   offset_pair_array_ = pair_array;
     263           0 :   set_model_changed();
     264           0 : }
     265             : 
     266           0 : IndexSubTableFormat4::Builder::Builder()
     267             :   : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable4_builderDataSize,
     268           0 :                            Format::FORMAT_4) {
     269           0 : }
     270             : 
     271           0 : IndexSubTableFormat4::Builder::Builder(WritableFontData* data,
     272             :                                        int32_t first_glyph_index,
     273           0 :                                        int32_t last_glyph_index)
     274           0 :     : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
     275           0 : }
     276             : 
     277           0 : IndexSubTableFormat4::Builder::Builder(ReadableFontData* data,
     278             :                                        int32_t first_glyph_index,
     279           0 :                                        int32_t last_glyph_index)
     280           0 :     : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
     281           0 : }
     282             : 
     283             : std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>*
     284           0 : IndexSubTableFormat4::Builder::GetOffsetArray() {
     285           0 :   if (offset_pair_array_.empty()) {
     286           0 :     Initialize(InternalReadData());
     287           0 :     set_model_changed();
     288             :   }
     289           0 :   return &offset_pair_array_;
     290             : }
     291             : 
     292           0 : void IndexSubTableFormat4::Builder::Initialize(ReadableFontData* data) {
     293           0 :   offset_pair_array_.clear();
     294           0 :   if (data) {
     295           0 :     int32_t num_pairs = IndexSubTableFormat4::NumGlyphs(data, 0) + 1;
     296           0 :     int32_t offset = EblcTable::Offset::kIndexSubTable4_glyphArray;
     297           0 :     for (int32_t i = 0; i < num_pairs; ++i) {
     298             :       int32_t glyph_code = data->ReadUShort(offset +
     299           0 :           EblcTable::Offset::kIndexSubTable4_codeOffsetPair_glyphCode);
     300           0 :       int32_t glyph_offset = data->ReadUShort(offset +
     301           0 :           EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset);
     302           0 :       offset += EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
     303           0 :       CodeOffsetPairBuilder pair_builder(glyph_code, glyph_offset);
     304           0 :       offset_pair_array_.push_back(pair_builder);
     305             :     }
     306             :   }
     307           0 : }
     308             : 
     309           0 : int32_t IndexSubTableFormat4::Builder::FindCodeOffsetPair(int32_t glyph_id) {
     310           0 :   std::vector<CodeOffsetPairBuilder>* pair_list = GetOffsetArray();
     311           0 :   int32_t location = 0;
     312           0 :   int32_t bottom = 0;
     313           0 :   int32_t top = pair_list->size();
     314           0 :   while (top != bottom) {
     315           0 :     location = (top + bottom) / 2;
     316           0 :     CodeOffsetPairBuilder* pair = &(pair_list->at(location));
     317           0 :     if (glyph_id < pair->glyph_code()) {
     318             :       // location is below current location
     319           0 :       top = location;
     320           0 :     } else if (glyph_id > pair->glyph_code()) {
     321             :       // location is above current location
     322           0 :       bottom = location + 1;
     323             :     } else {
     324           0 :       return location;
     325             :     }
     326             :   }
     327           0 :   return -1;
     328             : }
     329             : 
     330             : // static
     331           0 : int32_t IndexSubTableFormat4::Builder::DataLength(
     332             :     ReadableFontData* data,
     333             :     int32_t index_sub_table_offset,
     334             :     int32_t first_glyph_index,
     335             :     int32_t last_glyph_index) {
     336             :   int32_t num_glyphs = IndexSubTableFormat4::NumGlyphs(data,
     337           0 :                                                        index_sub_table_offset);
     338             :   UNREFERENCED_PARAMETER(first_glyph_index);
     339             :   UNREFERENCED_PARAMETER(last_glyph_index);
     340           0 :   return EblcTable::Offset::kIndexSubTable4_glyphArray +
     341           0 :          num_glyphs * EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset;
     342             : }
     343             : 
     344             : 
     345             : /******************************************************************************
     346             :  * IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator class
     347             :  ******************************************************************************/
     348           0 : IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
     349           0 :     IndexSubTableFormat4::Builder* container)
     350             :     : RefIterator<BitmapGlyphInfo, IndexSubTableFormat4::Builder,
     351             :                   IndexSubTable::Builder>(container),
     352           0 :       code_offset_pair_index_(0) {
     353           0 : }
     354             : 
     355           0 : bool IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::HasNext() {
     356           0 :   if (code_offset_pair_index_ <
     357           0 :       (int32_t)(container()->GetOffsetArray()->size() - 1)) {
     358           0 :     return true;
     359             :   }
     360           0 :   return false;
     361             : }
     362             : 
     363             : CALLER_ATTACH BitmapGlyphInfo*
     364           0 : IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::Next() {
     365           0 :   BitmapGlyphInfoPtr output;
     366           0 :   if (!HasNext()) {
     367             :     // Note: In C++, we do not throw exception when there's no element.
     368           0 :     return NULL;
     369             :   }
     370             :   std::vector<CodeOffsetPairBuilder>* offset_array =
     371           0 :       container()->GetOffsetArray();
     372           0 :   int32_t offset = offset_array->at(code_offset_pair_index_).offset();
     373           0 :   int32_t next_offset = offset_array->at(code_offset_pair_index_ + 1).offset();
     374           0 :   int32_t glyph_code = offset_array->at(code_offset_pair_index_).glyph_code();
     375             :   output = new BitmapGlyphInfo(glyph_code,
     376           0 :                                container()->image_data_offset(),
     377             :                                offset,
     378             :                                next_offset - offset,
     379           0 :                                container()->image_format());
     380           0 :   code_offset_pair_index_++;
     381           0 :   return output.Detach();
     382             : }
     383             : 
     384             : }  // namespace sfntly

Generated by: LCOV version 1.13