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/core/horizontal_metrics_table.h" 18 #include "sfntly/port/exception_type.h" 19 20 namespace sfntly { 21 /****************************************************************************** 22 * HorizontalMetricsTable class 23 ******************************************************************************/ 24 HorizontalMetricsTable::~HorizontalMetricsTable() {} 25 26 int32_t HorizontalMetricsTable::NumberOfHMetrics() { 27 return num_hmetrics_; 28 } 29 30 int32_t HorizontalMetricsTable::NumberOfLSBs() { 31 return num_glyphs_ - num_hmetrics_; 32 } 33 34 int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) { 35 if (entry > num_hmetrics_) { 36 #if !defined (SFNTLY_NO_EXCEPTION) 37 throw IndexOutOfBoundException(); 38 #endif 39 return 0; 40 } 41 int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + 42 Offset::kHMetricsAdvanceWidth; 43 return data_->ReadUShort(offset); 44 } 45 46 int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) { 47 if (entry > num_hmetrics_) { 48 #if !defined (SFNTLY_NO_EXCEPTION) 49 throw IndexOutOfBoundException(); 50 #endif 51 return 0; 52 } 53 int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + 54 Offset::kHMetricsLeftSideBearing; 55 return data_->ReadShort(offset); 56 } 57 58 int32_t HorizontalMetricsTable::LsbTableEntry(int32_t entry) { 59 if (entry > num_hmetrics_) { 60 #if !defined (SFNTLY_NO_EXCEPTION) 61 throw IndexOutOfBoundException(); 62 #endif 63 return 0; 64 } 65 int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) + 66 Offset::kLeftSideBearingSize; 67 return data_->ReadShort(offset); 68 } 69 70 int32_t HorizontalMetricsTable::AdvanceWidth(int32_t glyph_id) { 71 if (glyph_id < num_hmetrics_) { 72 return HMetricAdvanceWidth(glyph_id); 73 } 74 return HMetricAdvanceWidth(glyph_id - num_hmetrics_); 75 } 76 77 int32_t HorizontalMetricsTable::LeftSideBearing(int32_t glyph_id) { 78 if (glyph_id < num_hmetrics_) { 79 return HMetricLSB(glyph_id); 80 } 81 return LsbTableEntry(glyph_id - num_hmetrics_); 82 } 83 84 HorizontalMetricsTable::HorizontalMetricsTable(Header* header, 85 ReadableFontData* data, 86 int32_t num_hmetrics, 87 int32_t num_glyphs) 88 : Table(header, data), 89 num_hmetrics_(num_hmetrics), 90 num_glyphs_(num_glyphs) { 91 } 92 93 /****************************************************************************** 94 * HorizontalMetricsTable::Builder class 95 ******************************************************************************/ 96 HorizontalMetricsTable::Builder::Builder(Header* header, WritableFontData* data) 97 : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) { 98 } 99 100 HorizontalMetricsTable::Builder::Builder(Header* header, ReadableFontData* data) 101 : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) { 102 } 103 104 HorizontalMetricsTable::Builder::~Builder() {} 105 106 CALLER_ATTACH FontDataTable* 107 HorizontalMetricsTable::Builder::SubBuildTable(ReadableFontData* data) { 108 FontDataTablePtr table = 109 new HorizontalMetricsTable(header(), data, num_hmetrics_, num_glyphs_); 110 return table.Detach(); 111 } 112 113 CALLER_ATTACH HorizontalMetricsTable::Builder* 114 HorizontalMetricsTable::Builder::CreateBuilder(Header* header, 115 WritableFontData* data) { 116 Ptr<HorizontalMetricsTable::Builder> builder; 117 builder = new HorizontalMetricsTable::Builder(header, data); 118 return builder.Detach(); 119 } 120 121 void HorizontalMetricsTable::Builder::SetNumberOfHMetrics( 122 int32_t num_hmetrics) { 123 assert(num_hmetrics >= 0); 124 num_hmetrics_ = num_hmetrics; 125 HorizontalMetricsTable* table = 126 down_cast<HorizontalMetricsTable*>(this->GetTable()); 127 table->num_hmetrics_ = num_hmetrics; 128 } 129 130 void HorizontalMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) { 131 assert(num_glyphs >= 0); 132 num_glyphs_ = num_glyphs; 133 HorizontalMetricsTable* table = 134 down_cast<HorizontalMetricsTable*>(this->GetTable()); 135 table->num_glyphs_ = num_glyphs; 136 } 137 138 } // namespace sfntly 139