LCOV - code coverage report
Current view: top level - gfx/sfntly/cpp/src/sfntly/table/truetype - glyph_table.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 375 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 98 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/truetype/glyph_table.h"
      18             : 
      19             : #include <stdlib.h>
      20             : 
      21             : #include "sfntly/port/exception_type.h"
      22             : 
      23             : namespace sfntly {
      24             : /******************************************************************************
      25             :  * Constants
      26             :  ******************************************************************************/
      27             : const int32_t GlyphTable::SimpleGlyph::kFLAG_ONCURVE = 1;
      28             : const int32_t GlyphTable::SimpleGlyph::kFLAG_XSHORT = 1 << 1;
      29             : const int32_t GlyphTable::SimpleGlyph::kFLAG_YSHORT = 1 << 2;
      30             : const int32_t GlyphTable::SimpleGlyph::kFLAG_REPEAT = 1 << 3;
      31             : const int32_t GlyphTable::SimpleGlyph::kFLAG_XREPEATSIGN = 1 << 4;
      32             : const int32_t GlyphTable::SimpleGlyph::kFLAG_YREPEATSIGN = 1 << 5;
      33             : 
      34             : const int32_t GlyphTable::CompositeGlyph::kFLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
      35             : const int32_t GlyphTable::CompositeGlyph::kFLAG_ARGS_ARE_XY_VALUES = 1 << 1;
      36             : const int32_t GlyphTable::CompositeGlyph::kFLAG_ROUND_XY_TO_GRID = 1 << 2;
      37             : const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_SCALE = 1 << 3;
      38             : const int32_t GlyphTable::CompositeGlyph::kFLAG_RESERVED = 1 << 4;
      39             : const int32_t GlyphTable::CompositeGlyph::kFLAG_MORE_COMPONENTS = 1 << 5;
      40             : const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
      41             : const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_TWO_BY_TWO = 1 << 7;
      42             : const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_INSTRUCTIONS = 1 << 8;
      43             : const int32_t GlyphTable::CompositeGlyph::kFLAG_USE_MY_METRICS = 1 << 9;
      44             : const int32_t GlyphTable::CompositeGlyph::kFLAG_OVERLAP_COMPOUND = 1 << 10;
      45             : const int32_t GlyphTable::CompositeGlyph::kFLAG_SCALED_COMPONENT_OFFSET = 1 << 11;
      46             : const int32_t GlyphTable::CompositeGlyph::kFLAG_UNSCALED_COMPONENT_OFFSET = 1 << 12;
      47             : 
      48             : /******************************************************************************
      49             :  * GlyphTable class
      50             :  ******************************************************************************/
      51           0 : GlyphTable::~GlyphTable() {
      52           0 : }
      53             : 
      54           0 : GlyphTable::Glyph* GlyphTable::GetGlyph(int32_t offset, int32_t length) {
      55           0 :   return GlyphTable::Glyph::GetGlyph(this, this->data_, offset, length);
      56             : }
      57             : 
      58           0 : GlyphTable::GlyphTable(Header* header, ReadableFontData* data)
      59           0 :     : SubTableContainerTable(header, data) {
      60           0 : }
      61             : 
      62             : /******************************************************************************
      63             :  * GlyphTable::Builder class
      64             :  ******************************************************************************/
      65           0 : GlyphTable::Builder::Builder(Header* header, ReadableFontData* data)
      66           0 :     : SubTableContainerTable::Builder(header, data) {
      67           0 : }
      68             : 
      69           0 : GlyphTable::Builder::~Builder() {
      70           0 : }
      71             : 
      72           0 : void GlyphTable::Builder::SetLoca(const IntegerList& loca) {
      73           0 :   loca_ = loca;
      74           0 :   set_model_changed(false);
      75           0 :   glyph_builders_.clear();
      76           0 : }
      77             : 
      78           0 : void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) {
      79           0 :   assert(locas);
      80           0 :   GlyphBuilderList* glyph_builders = GetGlyphBuilders();
      81           0 :   locas->push_back(0);
      82           0 :   if (glyph_builders->size() == 0) {
      83           0 :     locas->push_back(0);
      84             :   } else {
      85           0 :     int32_t total = 0;
      86           0 :     for (GlyphBuilderList::iterator b = glyph_builders->begin(),
      87           0 :                                     b_end = glyph_builders->end();
      88             :                                     b != b_end; ++b) {
      89           0 :       int32_t size = (*b)->SubDataSizeToSerialize();
      90           0 :       locas->push_back(total + size);
      91           0 :       total += size;
      92             :     }
      93             :   }
      94           0 : }
      95             : 
      96             : CALLER_ATTACH GlyphTable::Builder*
      97           0 :     GlyphTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
      98           0 :   Ptr<GlyphTable::Builder> builder;
      99           0 :   builder = new GlyphTable::Builder(header, data);
     100           0 :   return builder.Detach();
     101             : }
     102             : 
     103           0 : GlyphTable::GlyphBuilderList* GlyphTable::Builder::GlyphBuilders() {
     104           0 :   return GetGlyphBuilders();
     105             : }
     106             : 
     107           0 : void GlyphTable::Builder::SetGlyphBuilders(GlyphBuilderList* glyph_builders) {
     108           0 :   glyph_builders_ = *glyph_builders;
     109           0 :   set_model_changed();
     110           0 : }
     111             : 
     112             : CALLER_ATTACH GlyphTable::Glyph::Builder*
     113           0 :     GlyphTable::Builder::GlyphBuilder(ReadableFontData* data) {
     114           0 :   return Glyph::Builder::GetBuilder(this, data);
     115             : }
     116             : 
     117             : CALLER_ATTACH FontDataTable*
     118           0 :     GlyphTable::Builder::SubBuildTable(ReadableFontData* data) {
     119           0 :   FontDataTablePtr table = new GlyphTable(header(), data);
     120           0 :   return table.Detach();
     121             : }
     122             : 
     123           0 : void GlyphTable::Builder::SubDataSet() {
     124           0 :   glyph_builders_.clear();
     125           0 :   set_model_changed(false);
     126           0 : }
     127             : 
     128           0 : int32_t GlyphTable::Builder::SubDataSizeToSerialize() {
     129           0 :   if (glyph_builders_.empty())
     130           0 :     return 0;
     131             : 
     132           0 :   bool variable = false;
     133           0 :   int32_t size = 0;
     134             : 
     135             :   // Calculate size of each table.
     136           0 :   for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
     137           0 :                                   end = glyph_builders_.end(); b != end; ++b) {
     138           0 :       int32_t glyph_size = (*b)->SubDataSizeToSerialize();
     139           0 :       size += abs(glyph_size);
     140           0 :       variable |= glyph_size <= 0;
     141             :   }
     142           0 :   return variable ? -size : size;
     143             : }
     144             : 
     145           0 : bool GlyphTable::Builder::SubReadyToSerialize() {
     146           0 :   return !glyph_builders_.empty();
     147             : }
     148             : 
     149           0 : int32_t GlyphTable::Builder::SubSerialize(WritableFontData* new_data) {
     150           0 :   int32_t size = 0;
     151           0 :   for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
     152           0 :                                   end = glyph_builders_.end(); b != end; ++b) {
     153           0 :     FontDataPtr data;
     154           0 :     data.Attach(new_data->Slice(size));
     155           0 :     size += (*b)->SubSerialize(down_cast<WritableFontData*>(data.p_));
     156             :   }
     157           0 :   return size;
     158             : }
     159             : 
     160           0 : void GlyphTable::Builder::Initialize(ReadableFontData* data,
     161             :                                      const IntegerList& loca) {
     162           0 :   if (data != NULL) {
     163           0 :     if (loca_.empty()) {
     164           0 :       return;
     165             :     }
     166             :     int32_t loca_value;
     167           0 :     int32_t last_loca_value = loca[0];
     168           0 :     for (size_t i = 1; i < loca.size(); ++i) {
     169           0 :       loca_value = loca[i];
     170           0 :       GlyphBuilderPtr builder;
     171           0 :       builder.Attach(
     172             :         Glyph::Builder::GetBuilder(this,
     173             :                                    data,
     174             :                                    last_loca_value /*offset*/,
     175           0 :                                    loca_value - last_loca_value /*length*/));
     176           0 :       glyph_builders_.push_back(builder);
     177           0 :       last_loca_value = loca_value;
     178             :     }
     179             :   }
     180             : }
     181             : 
     182           0 : GlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() {
     183           0 :   if (glyph_builders_.empty()) {
     184           0 :     if (InternalReadData() && !loca_.empty()) {
     185             : #if !defined (SFNTLY_NO_EXCEPTION)
     186             :       throw IllegalStateException(
     187             :           "Loca values not set - unable to parse glyph data.");
     188             : #endif
     189           0 :       return NULL;
     190             :     }
     191           0 :     Initialize(InternalReadData(), loca_);
     192           0 :     set_model_changed();
     193             :   }
     194           0 :   return &glyph_builders_;
     195             : }
     196             : 
     197           0 : void GlyphTable::Builder::Revert() {
     198           0 :   glyph_builders_.clear();
     199           0 :   set_model_changed(false);
     200           0 : }
     201             : 
     202             : /******************************************************************************
     203             :  * GlyphTable::Glyph class
     204             :  ******************************************************************************/
     205           0 : GlyphTable::Glyph::~Glyph() {}
     206             : 
     207             : CALLER_ATTACH GlyphTable::Glyph*
     208           0 :     GlyphTable::Glyph::GetGlyph(GlyphTable* table,
     209             :                                 ReadableFontData* data,
     210             :                                 int32_t offset,
     211             :                                 int32_t length) {
     212             :   UNREFERENCED_PARAMETER(table);
     213           0 :   int32_t type = GlyphType(data, offset, length);
     214           0 :   GlyphPtr glyph;
     215             : 
     216           0 :   ReadableFontDataPtr sliced_data;
     217           0 :   sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
     218           0 :   if (sliced_data) {
     219           0 :     if (type == GlyphType::kSimple)
     220           0 :       glyph = new SimpleGlyph(sliced_data);
     221             :     else
     222           0 :       glyph = new CompositeGlyph(sliced_data);
     223             :   }
     224           0 :   return glyph.Detach();
     225             : }
     226             : 
     227           0 : int32_t GlyphTable::Glyph::Padding() {
     228           0 :   Initialize();
     229           0 :   return SubTable::Padding();
     230             : }
     231             : 
     232           0 : int32_t GlyphTable::Glyph::GlyphType() {
     233           0 :   return glyph_type_;
     234             : }
     235             : 
     236           0 : int32_t GlyphTable::Glyph::NumberOfContours() {
     237           0 :   return number_of_contours_;
     238             : }
     239             : 
     240           0 : int32_t GlyphTable::Glyph::XMin() {
     241           0 :   return data_->ReadShort(Offset::kXMin);
     242             : }
     243             : 
     244           0 : int32_t GlyphTable::Glyph::XMax() {
     245           0 :   return data_->ReadShort(Offset::kXMax);
     246             : }
     247             : 
     248           0 : int32_t GlyphTable::Glyph::YMin() {
     249           0 :   return data_->ReadShort(Offset::kYMin);
     250             : }
     251             : 
     252           0 : int32_t GlyphTable::Glyph::YMax() {
     253           0 :   return data_->ReadShort(Offset::kYMax);
     254             : }
     255             : 
     256           0 : GlyphTable::Glyph::Glyph(ReadableFontData* data, int32_t glyph_type)
     257             :     : SubTable(data),
     258           0 :       glyph_type_(glyph_type) {
     259           0 :   if (data_->Length() == 0) {
     260           0 :     number_of_contours_ = 0;
     261             :   } else {
     262             :     // -1 if composite
     263           0 :     number_of_contours_ = data_->ReadShort(Offset::kNumberOfContours);
     264             :   }
     265           0 : }
     266             : 
     267           0 : int32_t GlyphTable::Glyph::GlyphType(ReadableFontData* data,
     268             :                                      int32_t offset,
     269             :                                      int32_t length) {
     270           0 :   if (length == 0) {
     271           0 :     return GlyphType::kSimple;
     272             :   }
     273           0 :   int32_t number_of_contours = data->ReadShort(offset);
     274           0 :   if (number_of_contours >= 0) {
     275           0 :     return GlyphType::kSimple;
     276             :   }
     277           0 :   return GlyphType::kComposite;
     278             : }
     279             : 
     280             : /******************************************************************************
     281             :  * GlyphTable::Glyph::Builder class
     282             :  ******************************************************************************/
     283           0 : GlyphTable::Glyph::Builder::~Builder() {
     284           0 : }
     285             : 
     286           0 : GlyphTable::Glyph::Builder::Builder(WritableFontData* data)
     287           0 :     : SubTable::Builder(data) {
     288           0 : }
     289             : 
     290           0 : GlyphTable::Glyph::Builder::Builder(ReadableFontData* data)
     291           0 :     : SubTable::Builder(data) {
     292           0 : }
     293             : 
     294             : CALLER_ATTACH GlyphTable::Glyph::Builder*
     295           0 :     GlyphTable::Glyph::Builder::GetBuilder(
     296             :         GlyphTable::Builder* table_builder,
     297             :         ReadableFontData* data) {
     298           0 :   return GetBuilder(table_builder, data, 0, data->Length());
     299             : }
     300             : 
     301             : CALLER_ATTACH GlyphTable::Glyph::Builder*
     302           0 :     GlyphTable::Glyph::Builder::GetBuilder(
     303             :         GlyphTable::Builder* table_builder,
     304             :         ReadableFontData* data,
     305             :         int32_t offset,
     306             :         int32_t length) {
     307             :   UNREFERENCED_PARAMETER(table_builder);
     308           0 :   int32_t type = Glyph::GlyphType(data, offset, length);
     309           0 :   GlyphBuilderPtr builder;
     310           0 :   ReadableFontDataPtr sliced_data;
     311           0 :   sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
     312           0 :   if (type == GlyphType::kSimple) {
     313           0 :     builder = new SimpleGlyph::SimpleGlyphBuilder(sliced_data);
     314             :   } else {
     315           0 :     builder = new CompositeGlyph::CompositeGlyphBuilder(sliced_data);
     316             :   }
     317           0 :   return builder.Detach();
     318             : }
     319             : 
     320           0 : void GlyphTable::Glyph::Builder::SubDataSet() {
     321             :   // NOP
     322           0 : }
     323             : 
     324           0 : int32_t GlyphTable::Glyph::Builder::SubDataSizeToSerialize() {
     325           0 :   return InternalReadData()->Length();
     326             : }
     327             : 
     328           0 : bool GlyphTable::Glyph::Builder::SubReadyToSerialize() {
     329           0 :   return true;
     330             : }
     331             : 
     332           0 : int32_t GlyphTable::Glyph::Builder::SubSerialize(WritableFontData* new_data) {
     333           0 :   return InternalReadData()->CopyTo(new_data);
     334             : }
     335             : 
     336             : /******************************************************************************
     337             :  * GlyphTable::SimpleGlyph
     338             :  ******************************************************************************/
     339           0 : GlyphTable::SimpleGlyph::SimpleGlyph(ReadableFontData* data)
     340           0 :     : GlyphTable::Glyph(data, GlyphType::kSimple), initialized_(false) {
     341           0 : }
     342             : 
     343           0 : GlyphTable::SimpleGlyph::~SimpleGlyph() {
     344           0 : }
     345             : 
     346           0 : int32_t GlyphTable::SimpleGlyph::InstructionSize() {
     347           0 :   Initialize();
     348           0 :   return instruction_size_;
     349             : }
     350             : 
     351           0 : CALLER_ATTACH ReadableFontData* GlyphTable::SimpleGlyph::Instructions() {
     352           0 :   Initialize();
     353           0 :   return down_cast<ReadableFontData*>(
     354           0 :              data_->Slice(instructions_offset_, InstructionSize()));
     355             : }
     356             : 
     357           0 : int32_t GlyphTable::SimpleGlyph::NumberOfPoints(int32_t contour) {
     358           0 :   Initialize();
     359           0 :   if (contour >= NumberOfContours()) {
     360           0 :     return 0;
     361             :   }
     362           0 :   return contour_index_[contour + 1] - contour_index_[contour];
     363             : }
     364             : 
     365           0 : int32_t GlyphTable::SimpleGlyph::XCoordinate(int32_t contour, int32_t point) {
     366           0 :   Initialize();
     367           0 :   return x_coordinates_[contour_index_[contour] + point];
     368             : }
     369             : 
     370           0 : int32_t GlyphTable::SimpleGlyph::YCoordinate(int32_t contour, int32_t point) {
     371           0 :   Initialize();
     372           0 :   return y_coordinates_[contour_index_[contour] + point];
     373             : }
     374             : 
     375           0 : bool GlyphTable::SimpleGlyph::OnCurve(int32_t contour, int32_t point) {
     376           0 :   Initialize();
     377           0 :   return on_curve_[contour_index_[contour] + point];
     378             : }
     379             : 
     380           0 : void GlyphTable::SimpleGlyph::Initialize() {
     381           0 :   AutoLock lock(initialization_lock_);
     382           0 :   if (initialized_) {
     383           0 :     return;
     384             :   }
     385             : 
     386           0 :   if (ReadFontData()->Length() == 0) {
     387           0 :     instruction_size_ = 0;
     388           0 :     number_of_points_ = 0;
     389           0 :     instructions_offset_ = 0;
     390           0 :     flags_offset_ = 0;
     391           0 :     x_coordinates_offset_ = 0;
     392           0 :     y_coordinates_offset_ = 0;
     393           0 :     return;
     394             :   }
     395             : 
     396           0 :   instruction_size_ = data_->ReadUShort(Offset::kSimpleEndPtsOfCountours +
     397           0 :       NumberOfContours() * DataSize::kUSHORT);
     398           0 :   instructions_offset_ = Offset::kSimpleEndPtsOfCountours +
     399           0 :       (NumberOfContours() + 1) * DataSize::kUSHORT;
     400           0 :   flags_offset_ = instructions_offset_ + instruction_size_ * DataSize::kBYTE;
     401           0 :   number_of_points_ = ContourEndPoint(NumberOfContours() - 1) + 1;
     402           0 :   x_coordinates_.resize(number_of_points_);
     403           0 :   y_coordinates_.resize(number_of_points_);
     404           0 :   on_curve_.resize(number_of_points_);
     405           0 :   ParseData(false);
     406           0 :   x_coordinates_offset_ = flags_offset_ + flag_byte_count_ * DataSize::kBYTE;
     407           0 :   y_coordinates_offset_ = x_coordinates_offset_ + x_byte_count_ *
     408             :       DataSize::kBYTE;
     409           0 :   contour_index_.resize(NumberOfContours() + 1);
     410           0 :   contour_index_[0] = 0;
     411           0 :   for (uint32_t contour = 0; contour < contour_index_.size() - 1; ++contour) {
     412           0 :     contour_index_[contour + 1] = ContourEndPoint(contour) + 1;
     413             :   }
     414           0 :   ParseData(true);
     415             :   int32_t non_padded_data_length =
     416           0 :     5 * DataSize::kSHORT +
     417           0 :     (NumberOfContours() * DataSize::kUSHORT) +
     418           0 :     DataSize::kUSHORT +
     419           0 :     (instruction_size_ * DataSize::kBYTE) +
     420           0 :     (flag_byte_count_ * DataSize::kBYTE) +
     421           0 :     (x_byte_count_ * DataSize::kBYTE) +
     422           0 :     (y_byte_count_ * DataSize::kBYTE);
     423           0 :   set_padding(DataLength() - non_padded_data_length);
     424           0 :   initialized_ = true;
     425             : }
     426             : 
     427           0 : void GlyphTable::SimpleGlyph::ParseData(bool fill_arrays) {
     428           0 :   int32_t flag = 0;
     429           0 :   int32_t flag_repeat = 0;
     430           0 :   int32_t flag_index = 0;
     431           0 :   int32_t x_byte_index = 0;
     432           0 :   int32_t y_byte_index = 0;
     433             : 
     434           0 :   for (int32_t point_index = 0; point_index < number_of_points_;
     435             :        ++point_index) {
     436             :     // get the flag for the current point
     437           0 :     if (flag_repeat == 0) {
     438           0 :       flag = FlagAsInt(flag_index++);
     439           0 :       if ((flag & kFLAG_REPEAT) == kFLAG_REPEAT) {
     440           0 :         flag_repeat = FlagAsInt(flag_index++);
     441             :       }
     442             :     } else {
     443           0 :       flag_repeat--;
     444             :     }
     445             : 
     446             :     // on the curve?
     447           0 :     if (fill_arrays) {
     448           0 :       on_curve_[point_index] = ((flag & kFLAG_ONCURVE) == kFLAG_ONCURVE);
     449             :     }
     450             :     // get the x coordinate
     451           0 :     if ((flag & kFLAG_XSHORT) == kFLAG_XSHORT) {
     452             :       // single byte x coord value
     453           0 :       if (fill_arrays) {
     454           0 :         x_coordinates_[point_index] =
     455           0 :             data_->ReadUByte(x_coordinates_offset_ + x_byte_index);
     456           0 :         x_coordinates_[point_index] *=
     457           0 :             ((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN) ? 1 : -1;
     458             :       }
     459           0 :       x_byte_index++;
     460             :     } else {
     461             :       // double byte coord value
     462           0 :       if (!((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN)) {
     463           0 :         if (fill_arrays) {
     464           0 :           x_coordinates_[point_index] =
     465           0 :             data_->ReadShort(x_coordinates_offset_ + x_byte_index);
     466             :         }
     467           0 :         x_byte_index += 2;
     468             :       }
     469             :     }
     470           0 :     if (fill_arrays && point_index > 0) {
     471           0 :       x_coordinates_[point_index] += x_coordinates_[point_index - 1];
     472             :     }
     473             : 
     474             :     // get the y coordinate
     475           0 :     if ((flag & kFLAG_YSHORT) == kFLAG_YSHORT) {
     476           0 :       if (fill_arrays) {
     477           0 :         y_coordinates_[point_index] =
     478           0 :           data_->ReadUByte(y_coordinates_offset_ + y_byte_index);
     479           0 :         y_coordinates_[point_index] *=
     480           0 :           ((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN) ? 1 : -1;
     481             :       }
     482           0 :       y_byte_index++;
     483             :     } else {
     484           0 :       if (!((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN)) {
     485           0 :         if (fill_arrays) {
     486           0 :           y_coordinates_[point_index] =
     487           0 :             data_->ReadShort(y_coordinates_offset_ + y_byte_index);
     488             :         }
     489           0 :         y_byte_index += 2;
     490             :       }
     491             :     }
     492           0 :     if (fill_arrays && point_index > 0) {
     493           0 :       y_coordinates_[point_index] += y_coordinates_[point_index - 1];
     494             :     }
     495             :   }
     496           0 :   flag_byte_count_ = flag_index;
     497           0 :   x_byte_count_ = x_byte_index;
     498           0 :   y_byte_count_ = y_byte_index;
     499           0 : }
     500             : 
     501           0 : int32_t GlyphTable::SimpleGlyph::FlagAsInt(int32_t index) {
     502           0 :   return data_->ReadUByte(flags_offset_ + index * DataSize::kBYTE);
     503             : }
     504             : 
     505           0 : int32_t GlyphTable::SimpleGlyph::ContourEndPoint(int32_t contour) {
     506           0 :   return data_->ReadUShort(contour * DataSize::kUSHORT +
     507           0 :                            Offset::kSimpleEndPtsOfCountours);
     508             : }
     509             : 
     510             : /******************************************************************************
     511             :  * GlyphTable::SimpleGlyph::Builder
     512             :  ******************************************************************************/
     513           0 : GlyphTable::SimpleGlyph::SimpleGlyphBuilder::~SimpleGlyphBuilder() {
     514           0 : }
     515             : 
     516           0 : GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
     517           0 :     WritableFontData* data)
     518           0 :     : Glyph::Builder(data) {
     519           0 : }
     520             : 
     521           0 : GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
     522           0 :     ReadableFontData* data)
     523           0 :     : Glyph::Builder(data) {
     524           0 : }
     525             : 
     526             : CALLER_ATTACH FontDataTable*
     527           0 :     GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SubBuildTable(
     528             :         ReadableFontData* data) {
     529           0 :   FontDataTablePtr table = new SimpleGlyph(data);
     530           0 :   return table.Detach();
     531             : }
     532             : 
     533             : /******************************************************************************
     534             :  * GlyphTable::CompositeGlyph
     535             :  ******************************************************************************/
     536           0 : GlyphTable::CompositeGlyph::CompositeGlyph(ReadableFontData* data)
     537             :     : GlyphTable::Glyph(data, GlyphType::kComposite),
     538             :       instruction_size_(0),
     539             :       instructions_offset_(0),
     540           0 :       initialized_(false) {
     541           0 :   Initialize();
     542           0 : }
     543             : 
     544           0 : GlyphTable::CompositeGlyph::~CompositeGlyph() {
     545           0 : }
     546             : 
     547           0 : int32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) {
     548           0 :   return data_->ReadUShort(contour_index_[contour]);
     549             : }
     550             : 
     551           0 : int32_t GlyphTable::CompositeGlyph::NumGlyphs() {
     552           0 :   return contour_index_.size();
     553             : }
     554             : 
     555           0 : int32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) {
     556           0 :   return data_->ReadUShort(DataSize::kUSHORT + contour_index_[contour]);
     557             : }
     558             : 
     559           0 : int32_t GlyphTable::CompositeGlyph::Argument1(int32_t contour) {
     560           0 :   int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
     561           0 :   int32_t contour_flags = Flags(contour);
     562           0 :   if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
     563             :                        kFLAG_ARG_1_AND_2_ARE_WORDS) {
     564           0 :     return data_->ReadUShort(index);
     565             :   }
     566           0 :   return data_->ReadByte(index);
     567             : }
     568             : 
     569           0 : int32_t GlyphTable::CompositeGlyph::Argument2(int32_t contour) {
     570           0 :   int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
     571           0 :   int32_t contour_flags = Flags(contour);
     572           0 :   if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
     573             :                        kFLAG_ARG_1_AND_2_ARE_WORDS) {
     574           0 :     return data_->ReadUShort(index + DataSize::kUSHORT);
     575             :   }
     576           0 :   return data_->ReadByte(index + DataSize::kUSHORT);
     577             : }
     578             : 
     579           0 : int32_t GlyphTable::CompositeGlyph::TransformationSize(int32_t contour) {
     580           0 :   int32_t contour_flags = Flags(contour);
     581           0 :   if ((contour_flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
     582           0 :       return DataSize::kF2DOT14;
     583           0 :     } else if ((contour_flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
     584             :                                 kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
     585           0 :       return 2 * DataSize::kF2DOT14;
     586           0 :     } else if ((contour_flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
     587             :                                 kFLAG_WE_HAVE_A_TWO_BY_TWO) {
     588           0 :       return 4 * DataSize::kF2DOT14;
     589             :     }
     590           0 :     return 0;
     591             : }
     592             : 
     593           0 : void GlyphTable::CompositeGlyph::Transformation(int32_t contour,
     594             :                                                 ByteVector* transformation) {
     595           0 :   int32_t contour_flags = Flags(contour);
     596           0 :   int32_t index = contour_index_[contour] + 2 * DataSize::kUSHORT;
     597           0 :   if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
     598             :                        kFLAG_ARG_1_AND_2_ARE_WORDS) {
     599           0 :     index += 2 * DataSize::kSHORT;
     600             :   } else {
     601           0 :     index += 2 * DataSize::kBYTE;
     602             :   }
     603           0 :   int32_t tsize = TransformationSize(contour);
     604           0 :   transformation->resize(tsize);
     605           0 :   data_->ReadBytes(index, &((*transformation)[0]), 0, tsize);
     606           0 : }
     607             : 
     608           0 : int32_t GlyphTable::CompositeGlyph::InstructionSize() {
     609           0 :   return instruction_size_;
     610             : }
     611             : 
     612           0 : CALLER_ATTACH ReadableFontData* GlyphTable::CompositeGlyph::Instructions() {
     613           0 :   return down_cast<ReadableFontData*>(
     614           0 :              data_->Slice(instructions_offset_, InstructionSize()));
     615             : }
     616             : 
     617           0 : void GlyphTable::CompositeGlyph::Initialize() {
     618           0 :   AutoLock lock(initialization_lock_);
     619           0 :   if (initialized_) {
     620           0 :     return;
     621             :   }
     622             : 
     623           0 :   int32_t index = 5 * DataSize::kUSHORT;
     624           0 :   int32_t flags = kFLAG_MORE_COMPONENTS;
     625             : 
     626           0 :   while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) {
     627           0 :     contour_index_.push_back(index);
     628           0 :     flags = data_->ReadUShort(index);
     629           0 :     index += 2 * DataSize::kUSHORT;  // flags and glyphIndex
     630           0 :     if ((flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == kFLAG_ARG_1_AND_2_ARE_WORDS) {
     631           0 :       index += 2 * DataSize::kSHORT;
     632             :     } else {
     633           0 :       index += 2 * DataSize::kBYTE;
     634             :     }
     635           0 :     if ((flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
     636           0 :       index += DataSize::kF2DOT14;
     637           0 :     } else if ((flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
     638             :                         kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
     639           0 :       index += 2 * DataSize::kF2DOT14;
     640           0 :     } else if ((flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
     641             :                         kFLAG_WE_HAVE_A_TWO_BY_TWO) {
     642           0 :       index += 4 * DataSize::kF2DOT14;
     643             :     }
     644           0 :     int32_t non_padded_data_length = index;
     645           0 :     if ((flags & kFLAG_WE_HAVE_INSTRUCTIONS) == kFLAG_WE_HAVE_INSTRUCTIONS) {
     646           0 :       instruction_size_ = data_->ReadUShort(index);
     647           0 :       index += DataSize::kUSHORT;
     648           0 :       instructions_offset_ = index;
     649           0 :       non_padded_data_length = index + (instruction_size_ * DataSize::kBYTE);
     650             :     }
     651           0 :     set_padding(DataLength() - non_padded_data_length);
     652             :   }
     653             : 
     654           0 :   initialized_ = true;
     655             : }
     656             : 
     657             : /******************************************************************************
     658             :  * GlyphTable::CompositeGlyph::Builder
     659             :  ******************************************************************************/
     660           0 : GlyphTable::CompositeGlyph::CompositeGlyphBuilder::~CompositeGlyphBuilder() {
     661           0 : }
     662             : 
     663           0 : GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
     664           0 :     WritableFontData* data)
     665           0 :     : Glyph::Builder(data) {
     666           0 : }
     667             : 
     668           0 : GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
     669           0 :     ReadableFontData* data)
     670           0 :     : Glyph::Builder(data) {
     671           0 : }
     672             : 
     673             : CALLER_ATTACH FontDataTable*
     674           0 :     GlyphTable::CompositeGlyph::CompositeGlyphBuilder::SubBuildTable(
     675             :         ReadableFontData* data) {
     676           0 :   FontDataTablePtr table = new CompositeGlyph(data);
     677           0 :   return table.Detach();
     678             : }
     679             : 
     680             : }  // namespace sfntly

Generated by: LCOV version 1.13