130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/truetype/glyph_table.h" 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdlib.h> 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/exception_type.h" 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Constants 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_ONCURVE = 1; 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_XSHORT = 1 << 1; 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_YSHORT = 1 << 2; 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_REPEAT = 1 << 3; 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_XREPEATSIGN = 1 << 4; 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::SimpleGlyph::kFLAG_YREPEATSIGN = 1 << 5; 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0; 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_ARGS_ARE_XY_VALUES = 1 << 1; 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_ROUND_XY_TO_GRID = 1 << 2; 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_SCALE = 1 << 3; 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_RESERVED = 1 << 4; 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_MORE_COMPONENTS = 1 << 5; 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_TWO_BY_TWO = 1 << 7; 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_INSTRUCTIONS = 1 << 8; 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_USE_MY_METRICS = 1 << 9; 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_OVERLAP_COMPOUND = 1 << 10; 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_SCALED_COMPONENT_OFFSET = 1 << 11; 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t GlyphTable::CompositeGlyph::kFLAG_UNSCALED_COMPONENT_OFFSET = 1 << 12; 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable class 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::~GlyphTable() { 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph* GlyphTable::GetGlyph(int32_t offset, int32_t length) { 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GlyphTable::Glyph::GetGlyph(this, this->data_, offset, length); 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::GlyphTable(Header* header, ReadableFontData* data) 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTableContainerTable(header, data) { 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::Builder class 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Builder::Builder(Header* header, ReadableFontData* data) 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTableContainerTable::Builder(header, data) { 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Builder::~Builder() { 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::SetLoca(const IntegerList& loca) { 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_ = loca; 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(false); 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_builders_.clear(); 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::GenerateLocaList(IntegerList* locas) { 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(locas); 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphBuilderList* glyph_builders = GetGlyphBuilders(); 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun locas->push_back(0); 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_builders->size() == 0) { 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun locas->push_back(0); 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t total = 0; 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (GlyphBuilderList::iterator b = glyph_builders->begin(), 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b_end = glyph_builders->end(); 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b != b_end; ++b) { 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = (*b)->SubDataSizeToSerialize(); 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun locas->push_back(total + size); 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun total += size; 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH GlyphTable::Builder* 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Builder::CreateBuilder(Header* header, WritableFontData* data) { 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Ptr<GlyphTable::Builder> builder; 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder = new GlyphTable::Builder(header, data); 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::GlyphBuilderList* GlyphTable::Builder::GlyphBuilders() { 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetGlyphBuilders(); 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::SetGlyphBuilders(GlyphBuilderList* glyph_builders) { 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_builders_ = *glyph_builders; 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH GlyphTable::Glyph::Builder* 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Builder::GlyphBuilder(ReadableFontData* data) { 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return Glyph::Builder::GetBuilder(this, data); 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Builder::SubBuildTable(ReadableFontData* data) { 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new GlyphTable(header(), data); 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::SubDataSet() { 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_builders_.clear(); 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(false); 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Builder::SubDataSizeToSerialize() { 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_builders_.empty()) 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun bool variable = false; 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = 0; 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Calculate size of each table. 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (GlyphBuilderList::iterator b = glyph_builders_.begin(), 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end = glyph_builders_.end(); b != end; ++b) { 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t glyph_size = (*b)->SubDataSizeToSerialize(); 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += abs(glyph_size); 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun variable |= glyph_size <= 0; 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return variable ? -size : size; 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool GlyphTable::Builder::SubReadyToSerialize() { 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return !glyph_builders_.empty(); 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Builder::SubSerialize(WritableFontData* new_data) { 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = 0; 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (GlyphBuilderList::iterator b = glyph_builders_.begin(), 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun end = glyph_builders_.end(); b != end; ++b) { 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataPtr data; 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data.Attach(new_data->Slice(size)); 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun size += (*b)->SubSerialize(down_cast<WritableFontData*>(data.p_)); 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return size; 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::Initialize(ReadableFontData* data, 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const IntegerList& loca) { 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data != NULL) { 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (loca_.empty()) { 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t loca_value; 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t last_loca_value = loca[0]; 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (size_t i = 1; i < loca.size(); ++i) { 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_value = loca[i]; 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphBuilderPtr builder; 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder.Attach( 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Glyph::Builder::GetBuilder(this, 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data, 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun last_loca_value /*offset*/, 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun loca_value - last_loca_value /*length*/)); 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_builders_.push_back(builder); 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun last_loca_value = loca_value; 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() { 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (glyph_builders_.empty()) { 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (InternalReadData() && !loca_.empty()) { 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION) 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun throw IllegalStateException( 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun "Loca values not set - unable to parse glyph data."); 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(InternalReadData(), loca_); 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(); 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return &glyph_builders_; 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Builder::Revert() { 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_builders_.clear(); 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_model_changed(false); 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::Glyph class 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph::~Glyph() {} 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH GlyphTable::Glyph* 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Glyph::GetGlyph(GlyphTable* table, 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data, 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length) { 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(table); 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t type = GlyphType(data, offset, length); 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphPtr glyph; 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr sliced_data; 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length))); 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (type == GlyphType::kSimple) { 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph = new SimpleGlyph(sliced_data); 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph = new CompositeGlyph(sliced_data); 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return glyph.Detach(); 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::Padding() { 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return SubTable::Padding(); 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::GlyphType() { 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return glyph_type_; 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::NumberOfContours() { 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return number_of_contours_; 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::XMin() { 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadShort(Offset::kXMin); 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::XMax() { 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadShort(Offset::kXMax); 24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::YMin() { 24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadShort(Offset::kYMin); 24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::YMax() { 25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadShort(Offset::kYMax); 25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph::Glyph(ReadableFontData* data, int32_t glyph_type) 25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable(data), 25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun glyph_type_(glyph_type) { 25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (data_->Length() == 0) { 25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun number_of_contours_ = 0; 26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // -1 if composite 26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun number_of_contours_ = data_->ReadShort(Offset::kNumberOfContours); 26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::GlyphType(ReadableFontData* data, 26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length) { 26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (length == 0) { 27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GlyphType::kSimple; 27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t number_of_contours = data->ReadShort(offset); 27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (number_of_contours >= 0) { 27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GlyphType::kSimple; 27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GlyphType::kComposite; 27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::Glyph::Builder class 28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph::Builder::~Builder() { 28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph::Builder::Builder(WritableFontData* data) 28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable::Builder(data) { 28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::Glyph::Builder::Builder(ReadableFontData* data) 29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : SubTable::Builder(data) { 29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH GlyphTable::Glyph::Builder* 29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Glyph::Builder::GetBuilder( 29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Builder* table_builder, 29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) { 29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return GetBuilder(table_builder, data, 0, data->Length()); 29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH GlyphTable::Glyph::Builder* 30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Glyph::Builder::GetBuilder( 30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::Builder* table_builder, 30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data, 30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t offset, 30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length) { 30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNREFERENCED_PARAMETER(table_builder); 30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t type = Glyph::GlyphType(data, offset, length); 30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphBuilderPtr builder; 30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr sliced_data; 31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length))); 31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (type == GlyphType::kSimple) { 31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder = new SimpleGlyph::SimpleGlyphBuilder(sliced_data); 31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun builder = new CompositeGlyph::CompositeGlyphBuilder(sliced_data); 31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return builder.Detach(); 31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::Glyph::Builder::SubDataSet() { 32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // NOP 32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::Builder::SubDataSizeToSerialize() { 32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return InternalReadData()->Length(); 32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool GlyphTable::Glyph::Builder::SubReadyToSerialize() { 32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::Glyph::Builder::SubSerialize(WritableFontData* new_data) { 33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return InternalReadData()->CopyTo(new_data); 33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::SimpleGlyph 33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 33830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::SimpleGlyph::SimpleGlyph(ReadableFontData* data) 33930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : GlyphTable::Glyph(data, GlyphType::kSimple), initialized_(false) { 34030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::SimpleGlyph::~SimpleGlyph() { 34330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 34530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::InstructionSize() { 34630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 34730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return instruction_size_; 34830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 34930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 35030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH ReadableFontData* GlyphTable::SimpleGlyph::Instructions() { 35130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 35230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return down_cast<ReadableFontData*>( 35330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->Slice(instructions_offset_, InstructionSize())); 35430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 35530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 35630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::NumberOfPoints(int32_t contour) { 35730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 35830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (contour >= NumberOfContours()) { 35930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 36030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 36130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return contour_index_[contour + 1] - contour_index_[contour]; 36230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 36330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::XCoordinate(int32_t contour, int32_t point) { 36530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 36630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return x_coordinates_[contour_index_[contour] + point]; 36730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 36830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 36930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::YCoordinate(int32_t contour, int32_t point) { 37030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 37130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return y_coordinates_[contour_index_[contour] + point]; 37230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 37330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool GlyphTable::SimpleGlyph::OnCurve(int32_t contour, int32_t point) { 37530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 37630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return on_curve_[contour_index_[contour] + point]; 37730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 37830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 37930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::SimpleGlyph::Initialize() { 38030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun AutoLock lock(initialization_lock_); 38130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (initialized_) { 38230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 38330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 38430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 38530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (ReadFontData()->Length() == 0) { 38630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instruction_size_ = 0; 38730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun number_of_points_ = 0; 38830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instructions_offset_ = 0; 38930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flags_offset_ = 0; 39030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_offset_ = 0; 39130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_offset_ = 0; 39230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 39330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 39430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 39530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instruction_size_ = data_->ReadUShort(Offset::kSimpleEndPtsOfCountours + 39630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun NumberOfContours() * DataSize::kUSHORT); 39730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instructions_offset_ = Offset::kSimpleEndPtsOfCountours + 39830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (NumberOfContours() + 1) * DataSize::kUSHORT; 39930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flags_offset_ = instructions_offset_ + instruction_size_ * DataSize::kBYTE; 40030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun number_of_points_ = ContourEndPoint(NumberOfContours() - 1) + 1; 40130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_.resize(number_of_points_); 40230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_.resize(number_of_points_); 40330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun on_curve_.resize(number_of_points_); 40430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ParseData(false); 40530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_offset_ = flags_offset_ + flag_byte_count_ * DataSize::kBYTE; 40630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_offset_ = x_coordinates_offset_ + x_byte_count_ * 40730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kBYTE; 40830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun contour_index_.resize(NumberOfContours() + 1); 40930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun contour_index_[0] = 0; 41030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (uint32_t contour = 0; contour < contour_index_.size() - 1; ++contour) { 41130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun contour_index_[contour + 1] = ContourEndPoint(contour) + 1; 41230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 41330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ParseData(true); 41430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t non_padded_data_length = 41530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5 * DataSize::kSHORT + 41630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (NumberOfContours() * DataSize::kUSHORT) + 41730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT + 41830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (instruction_size_ * DataSize::kBYTE) + 41930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (flag_byte_count_ * DataSize::kBYTE) + 42030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (x_byte_count_ * DataSize::kBYTE) + 42130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (y_byte_count_ * DataSize::kBYTE); 42230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_padding(DataLength() - non_padded_data_length); 42330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun initialized_ = true; 42430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 42530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 42630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::SimpleGlyph::ParseData(bool fill_arrays) { 42730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t flag = 0; 42830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t flag_repeat = 0; 42930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t flag_index = 0; 43030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t x_byte_index = 0; 43130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t y_byte_index = 0; 43230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 43330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t point_index = 0; point_index < number_of_points_; 43430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ++point_index) { 43530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // get the flag for the current point 43630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (flag_repeat == 0) { 43730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flag = FlagAsInt(flag_index++); 43830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flag & kFLAG_REPEAT) == kFLAG_REPEAT) { 43930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flag_repeat = FlagAsInt(flag_index++); 44030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 44130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 44230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flag_repeat--; 44330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 44430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 44530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // on the curve? 44630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays) { 44730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun on_curve_[point_index] = ((flag & kFLAG_ONCURVE) == kFLAG_ONCURVE); 44830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 44930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // get the x coordinate 45030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flag & kFLAG_XSHORT) == kFLAG_XSHORT) { 45130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // single byte x coord value 45230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays) { 45330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_[point_index] = 45430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->ReadUByte(x_coordinates_offset_ + x_byte_index); 45530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_[point_index] *= 45630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN) ? 1 : -1; 45730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 45830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_byte_index++; 45930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 46030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // double byte coord value 46130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN)) { 46230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays) { 46330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_[point_index] = 46430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->ReadShort(x_coordinates_offset_ + x_byte_index); 46530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_byte_index += 2; 46730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 46930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays && point_index > 0) { 47030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_coordinates_[point_index] += x_coordinates_[point_index - 1]; 47130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 47230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 47330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // get the y coordinate 47430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flag & kFLAG_YSHORT) == kFLAG_YSHORT) { 47530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays) { 47630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_[point_index] = 47730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->ReadUByte(y_coordinates_offset_ + y_byte_index); 47830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_[point_index] *= 47930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN) ? 1 : -1; 48030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 48130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_byte_index++; 48230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 48330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN)) { 48430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays) { 48530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_[point_index] = 48630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->ReadShort(y_coordinates_offset_ + y_byte_index); 48730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 48830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_byte_index += 2; 48930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (fill_arrays && point_index > 0) { 49230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_coordinates_[point_index] += y_coordinates_[point_index - 1]; 49330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 49530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flag_byte_count_ = flag_index; 49630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun x_byte_count_ = x_byte_index; 49730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun y_byte_count_ = y_byte_index; 49830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 49930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::FlagAsInt(int32_t index) { 50130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUByte(flags_offset_ + index * DataSize::kBYTE); 50230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 50330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::SimpleGlyph::ContourEndPoint(int32_t contour) { 50530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(contour * DataSize::kUSHORT + 50630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Offset::kSimpleEndPtsOfCountours); 50730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 50830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 50930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 51030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::SimpleGlyph::Builder 51130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 51230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::SimpleGlyph::SimpleGlyphBuilder::~SimpleGlyphBuilder() { 51330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 51430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 51530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder( 51630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* data) 51730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Glyph::Builder(data) { 51830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 51930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 52030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder( 52130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) 52230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Glyph::Builder(data) { 52330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 52430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 52530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 52630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SubBuildTable( 52730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) { 52830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new SimpleGlyph(data); 52930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 53030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 53130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 53230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 53330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::CompositeGlyph 53430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 53530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::CompositeGlyph::CompositeGlyph(ReadableFontData* data) 53630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : GlyphTable::Glyph(data, GlyphType::kComposite), 53730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instruction_size_(0), 53830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instructions_offset_(0), 53930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun initialized_(false) { 54030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Initialize(); 54130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 54230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 54330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::CompositeGlyph::~CompositeGlyph() { 54430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 54530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 54630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) { 54730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(contour_index_[contour]); 54830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 54930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::NumGlyphs() { 55130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return contour_index_.size(); 55230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 55330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) { 55530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(DataSize::kUSHORT + contour_index_[contour]); 55630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 55730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 55830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::Argument1(int32_t contour) { 55930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour]; 56030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t contour_flags = Flags(contour); 56130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == 56230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_ARG_1_AND_2_ARE_WORDS) { 56330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(index); 56430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 56530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadByte(index); 56630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 56730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 56830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::Argument2(int32_t contour) { 56930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour]; 57030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t contour_flags = Flags(contour); 57130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == 57230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_ARG_1_AND_2_ARE_WORDS) { 57330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadUShort(index + DataSize::kUSHORT); 57430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 57530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return data_->ReadByte(index + DataSize::kUSHORT); 57630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 57730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 57830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::TransformationSize(int32_t contour) { 57930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t contour_flags = Flags(contour); 58030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((contour_flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) { 58130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return DataSize::kF2DOT14; 58230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else if ((contour_flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) == 58330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) { 58430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 2 * DataSize::kF2DOT14; 58530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else if ((contour_flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) == 58630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_WE_HAVE_A_TWO_BY_TWO) { 58730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 4 * DataSize::kF2DOT14; 58830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 58930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 59030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 59130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 59230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::CompositeGlyph::Transformation(int32_t contour, 59330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector* transformation) { 59430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t contour_flags = Flags(contour); 59530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = contour_index_[contour] + 2 * DataSize::kUSHORT; 59630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == 59730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_ARG_1_AND_2_ARE_WORDS) { 59830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kSHORT; 59930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 60030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kBYTE; 60130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 60230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t tsize = TransformationSize(contour); 60330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun transformation->resize(tsize); 60430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->ReadBytes(index, &((*transformation)[0]), 0, tsize); 60530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 60630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 60730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t GlyphTable::CompositeGlyph::InstructionSize() { 60830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return instruction_size_; 60930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 61030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 61130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH ReadableFontData* GlyphTable::CompositeGlyph::Instructions() { 61230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return down_cast<ReadableFontData*>( 61330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun data_->Slice(instructions_offset_, InstructionSize())); 61430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 61530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 61630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid GlyphTable::CompositeGlyph::Initialize() { 61730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun AutoLock lock(initialization_lock_); 61830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (initialized_) { 61930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return; 62030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 62130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 62230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 5 * DataSize::kUSHORT; 62330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t flags = kFLAG_MORE_COMPONENTS; 62430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 62530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) { 62630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun contour_index_.push_back(index); 62730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun flags = data_->ReadUShort(index); 62830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kUSHORT; // flags and glyphIndex 62930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == kFLAG_ARG_1_AND_2_ARE_WORDS) { 63030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kSHORT; 63130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else { 63230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kBYTE; 63330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 63430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) { 63530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += DataSize::kF2DOT14; 63630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else if ((flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) == 63730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) { 63830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 2 * DataSize::kF2DOT14; 63930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } else if ((flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) == 64030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kFLAG_WE_HAVE_A_TWO_BY_TWO) { 64130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += 4 * DataSize::kF2DOT14; 64230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 64330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t non_padded_data_length = index; 64430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if ((flags & kFLAG_WE_HAVE_INSTRUCTIONS) == kFLAG_WE_HAVE_INSTRUCTIONS) { 64530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instruction_size_ = data_->ReadUShort(index); 64630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += DataSize::kUSHORT; 64730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun instructions_offset_ = index; 64830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun non_padded_data_length = index + (instruction_size_ * DataSize::kBYTE); 64930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 65030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun set_padding(DataLength() - non_padded_data_length); 65130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 65230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 65330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun initialized_ = true; 65430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 65530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 65630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/****************************************************************************** 65730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * GlyphTable::CompositeGlyph::Builder 65830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/ 65930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::CompositeGlyph::CompositeGlyphBuilder::~CompositeGlyphBuilder() { 66030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 66130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 66230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder( 66330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* data) 66430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Glyph::Builder(data) { 66530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 66630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 66730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunGlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder( 66830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) 66930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : Glyph::Builder(data) { 67030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 67130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 67230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH FontDataTable* 67330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun GlyphTable::CompositeGlyph::CompositeGlyphBuilder::SubBuildTable( 67430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* data) { 67530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FontDataTablePtr table = new CompositeGlyph(data); 67630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return table.Detach(); 67730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 67830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 67930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 680