diff options
author | arthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51> | 2011-11-15 19:34:35 +0000 |
---|---|---|
committer | arthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51> | 2011-11-15 19:34:35 +0000 |
commit | a7acde600e171e08e75138318308de83f38b3097 (patch) | |
tree | 00c68d6768025720b4e8cc0e719099f1fd63ead7 | |
parent | 144e5cb2b372c30d8a4b90267b52646368dd89fc (diff) | |
download | src-a7acde600e171e08e75138318308de83f38b3097.tar.gz |
Update to Java initial release (except bitmap tables)
TBR(stuartg)
git-svn-id: http://sfntly.googlecode.com/svn/trunk/cpp/src@105 672e30a5-4c29-85ac-ac6d-611c735e0a51
-rw-r--r-- | sfntly/font.cc | 17 | ||||
-rw-r--r-- | sfntly/table/core/horizontal_device_metrics_table.cc | 124 | ||||
-rw-r--r-- | sfntly/table/core/horizontal_device_metrics_table.h | 82 | ||||
-rw-r--r-- | sfntly/table/table.cc | 21 | ||||
-rw-r--r-- | test/hdmx_test.cc | 82 |
5 files changed, 319 insertions, 7 deletions
diff --git a/sfntly/font.cc b/sfntly/font.cc index 3fa77b0..c9798c8 100644 --- a/sfntly/font.cc +++ b/sfntly/font.cc @@ -31,6 +31,7 @@ #include "sfntly/math/font_math.h" #include "sfntly/port/exception_type.h" #include "sfntly/table/core/font_header_table.h" +#include "sfntly/table/core/horizontal_device_metrics_table.h" #include "sfntly/table/core/horizontal_header_table.h" #include "sfntly/table/core/horizontal_metrics_table.h" #include "sfntly/table/core/maximum_profile_table.h" @@ -435,6 +436,15 @@ void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder); } +#if defined (SFNTLY_EXPERIMENTAL) + Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx); + HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder; + if (raw_hdmx_builder != NULL) { + hdmx_table_builder = + down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder); + } +#endif + // set the inter table data required to build certain tables if (horizontal_metrics_builder != NULL) { if (max_profile_builder != NULL) { @@ -456,6 +466,13 @@ void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) { header_table_builder->IndexToLocFormat()); } } + +#if defined (SFNTLY_EXPERIMENTAL) + // Note: In C++, hdmx_table_builder can be NULL in a subsetter. + if (max_profile_builder != NULL && hdmx_table_builder != NULL) { + hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs()); + } +#endif } void Font::Builder::ReadHeader(FontInputStream* is, diff --git a/sfntly/table/core/horizontal_device_metrics_table.cc b/sfntly/table/core/horizontal_device_metrics_table.cc new file mode 100644 index 0000000..34d03e6 --- /dev/null +++ b/sfntly/table/core/horizontal_device_metrics_table.cc @@ -0,0 +1,124 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sfntly/table/core/horizontal_device_metrics_table.h" + +namespace sfntly { +/****************************************************************************** + * HorizontalDeviceMetricsTable class + ******************************************************************************/ +HorizontalDeviceMetricsTable:: ~HorizontalDeviceMetricsTable() {} + +int32_t HorizontalDeviceMetricsTable::Version() { + return data_->ReadUShort(Offset::kVersion); +} + +int32_t HorizontalDeviceMetricsTable::NumRecords() { + return data_->ReadShort(Offset::kNumRecords); +} + +int32_t HorizontalDeviceMetricsTable::RecordSize() { + return data_->ReadLong(Offset::kSizeDeviceRecord); +} + +int32_t HorizontalDeviceMetricsTable::PixelSize(int32_t record_index) { + if (record_index < 0 || record_index >= NumRecords()) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException(); +#endif + return -1; + } + return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() + + Offset::kDeviceRecordPixelSize); +} + +int32_t HorizontalDeviceMetricsTable::MaxWidth(int32_t record_index) { + if (record_index < 0 || record_index >= NumRecords()) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException(); +#endif + return -1; + } + return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() + + Offset::kDeviceRecordMaxWidth); +} + +int32_t HorizontalDeviceMetricsTable::Width(int32_t record_index, + int32_t glyph_num) { + if (record_index < 0 || record_index >= NumRecords() || + glyph_num < 0 || glyph_num >= num_glyphs_) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IndexOutOfBoundsException(); +#endif + return -1; + } + return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() + + Offset::kDeviceRecordWidths + glyph_num); +} + +HorizontalDeviceMetricsTable::HorizontalDeviceMetricsTable( + Header* header, + ReadableFontData* data, + int32_t num_glyphs) + : Table(header, data), num_glyphs_(num_glyphs) { +} + +/****************************************************************************** + * HorizontalDeviceMetricsTable::Builder class + ******************************************************************************/ +HorizontalDeviceMetricsTable::Builder::Builder(Header* header, + WritableFontData* data) + : TableBasedTableBuilder(header, data), num_glyphs_(-1) { +} + +HorizontalDeviceMetricsTable::Builder::Builder(Header* header, + ReadableFontData* data) + : TableBasedTableBuilder(header, data), num_glyphs_(-1) { +} + +HorizontalDeviceMetricsTable::Builder::~Builder() {} + +CALLER_ATTACH FontDataTable* +HorizontalDeviceMetricsTable::Builder::SubBuildTable(ReadableFontData* data) { + FontDataTablePtr table = new HorizontalDeviceMetricsTable(header(), data, + num_glyphs_); + return table.Detach(); +} + +void HorizontalDeviceMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) { + if (num_glyphs < 0) { +#if !defined (SFNTLY_NO_EXCEPTION) + throw IllegalArgumentException("Number of glyphs can't be negative."); + return; +#endif + } + num_glyphs_ = num_glyphs; + HorizontalDeviceMetricsTable* table = + down_cast<HorizontalDeviceMetricsTable*>(GetTable()); + if (table) { + table->num_glyphs_ = num_glyphs; + } +} + +CALLER_ATTACH HorizontalDeviceMetricsTable::Builder* +HorizontalDeviceMetricsTable::Builder::CreateBuilder(Header* header, + WritableFontData* data) { + Ptr<HorizontalDeviceMetricsTable::Builder> builder; + builder = new HorizontalDeviceMetricsTable::Builder(header, data); + return builder.Detach(); +} + +} // namespace sfntly diff --git a/sfntly/table/core/horizontal_device_metrics_table.h b/sfntly/table/core/horizontal_device_metrics_table.h new file mode 100644 index 0000000..4a27ba0 --- /dev/null +++ b/sfntly/table/core/horizontal_device_metrics_table.h @@ -0,0 +1,82 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_ +#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_ + +#include "sfntly/table/table.h" +#include "sfntly/table/table_based_table_builder.h" + +namespace sfntly { + +// A Horizontal Device Metrics table - 'hdmx' +class HorizontalDeviceMetricsTable + : public Table, + public RefCounted<HorizontalDeviceMetricsTable> { + public: + class Builder : public TableBasedTableBuilder, public RefCounted<Builder> { + public: + // Constructor scope altered to public because C++ does not allow base + // class to instantiate derived class with protected constructors. + Builder(Header* header, WritableFontData* data); + Builder(Header* header, ReadableFontData* data); + virtual ~Builder(); + virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data); + + static CALLER_ATTACH Builder* CreateBuilder(Header* header, + WritableFontData* data); + + void SetNumGlyphs(int32_t num_glyphs); + + private: + int32_t num_glyphs_; + }; + + virtual ~HorizontalDeviceMetricsTable(); + + int32_t Version(); + int32_t NumRecords(); + int32_t RecordSize(); + int32_t PixelSize(int32_t record_index); + int32_t MaxWidth(int32_t record_index); + int32_t Width(int32_t record_index, int32_t glyph_num); + + private: + struct Offset { + enum { + kVersion = 0,
+ kNumRecords = 2,
+ kSizeDeviceRecord = 4,
+ kRecords = 8,
+
+ // Offsets within a device record
+ kDeviceRecordPixelSize = 0,
+ kDeviceRecordMaxWidth = 1,
+ kDeviceRecordWidths = 2, + }; + }; + HorizontalDeviceMetricsTable(Header* header, + ReadableFontData* data, + int32_t num_glyphs); + + int32_t num_glyphs_; +}; +typedef Ptr<HorizontalDeviceMetricsTable> HorizontalDeviceMetricsTablePtr; +typedef Ptr<HorizontalDeviceMetricsTable::Builder> + HorizontalDeviceMetricsTableBuilderPtr; +} // namespace sfntly + +#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_ diff --git a/sfntly/table/table.cc b/sfntly/table/table.cc index f1ff63d..63b1aff 100644 --- a/sfntly/table/table.cc +++ b/sfntly/table/table.cc @@ -24,8 +24,10 @@ #include "sfntly/tag.h" #include "sfntly/table/bitmap/ebdt_table.h" #include "sfntly/table/bitmap/eblc_table.h" +#include "sfntly/table/bitmap/ebsc_table.h" #include "sfntly/table/core/cmap_table.h" #include "sfntly/table/core/font_header_table.h" +#include "sfntly/table/core/horizontal_device_metrics_table.h" #include "sfntly/table/core/horizontal_header_table.h" #include "sfntly/table/core/horizontal_metrics_table.h" #include "sfntly/table/core/maximum_profile_table.h" @@ -82,11 +84,11 @@ Table::Builder* Table::Builder::GetBuilder(Header* header, if (tag == Tag::head) { builder_raw = static_cast<Table::Builder*>( FontHeaderTable::Builder::CreateBuilder(header, table_data)); -#if defined (SFNTLY_ENABLE_CMAP_HANDLING) +#if defined (SFNTLY_EXPERIMENTAL) } else if (tag == Tag::cmap) { builder_raw = static_cast<Table::Builder*>( CMapTable::Builder::CreateBuilder(header, table_data)); -#endif // SFNTLY_ENABLE_CMAP_HANDLING +#endif // SFNTLY_EXPERIMENTAL } else if (tag == Tag::hhea) { builder_raw = static_cast<Table::Builder*>( HorizontalHeaderTable::Builder::CreateBuilder(header, table_data)); @@ -114,24 +116,29 @@ Table::Builder* Table::Builder::GetBuilder(Header* header, } else if (tag == Tag::loca) { builder_raw = static_cast<Table::Builder*>( LocaTable::Builder::CreateBuilder(header, table_data)); -#if defined (SFNTLY_ENABLE_BITMAP_HANDLING) +#if defined (SFNTLY_EXPERIMENTAL) } else if (tag == Tag::EBDT || tag == Tag::bdat) { builder_raw = static_cast<Table::Builder*>( EbdtTable::Builder::CreateBuilder(header, table_data)); } else if (tag == Tag::EBLC || tag == Tag::bloc) { builder_raw = static_cast<Table::Builder*>( EblcTable::Builder::CreateBuilder(header, table_data)); -#endif // SFNTLY_ENABLE_BITMAP_HANDLING - } /* else if (tag == Tag::EBSC) { + } else if (tag == Tag::EBSC) { builder_raw = static_cast<Table::Builder*>( EbscTable::Builder::CreateBuilder(header, table_data)); - }*/ - /* else if (tag == Tag::prep) { +#endif // SFNTLY_EXPERIMENTAL + } /* else if (tag == Tag::prep) { builder_raw = static_cast<Table::Builder*>( ControlProgramTable::Builder::CreateBuilder(header, table_data)); }*/ else if (tag == Tag::bhed) { builder_raw = static_cast<Table::Builder*>( FontHeaderTable::Builder::CreateBuilder(header, table_data)); +#if defined (SFNTLY_EXPERIMENTAL) + } else if (tag == Tag::hdmx) { + builder_raw = static_cast<Table::Builder*>( + HorizontalDeviceMetricsTable::Builder::CreateBuilder(header, + table_data)); +#endif // SFNTLY_EXPERIMENTAL } else { builder_raw = static_cast<Table::Builder*>( GenericTableBuilder::CreateBuilder(header, table_data)); diff --git a/test/hdmx_test.cc b/test/hdmx_test.cc new file mode 100644 index 0000000..cdc4ed0 --- /dev/null +++ b/test/hdmx_test.cc @@ -0,0 +1,82 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" +#include "sfntly/font.h" +#include "sfntly/table/core/horizontal_device_metrics_table.h" +#include "test/test_data.h" +#include "test/test_font_utils.h" + +namespace sfntly { + +const int32_t HDMX_VERSION = 0; +const int32_t HDMX_NUM_RECORDS = 4; +const int32_t HDMX_RECORD_SIZE = 628; +const int32_t HDMX_PIXEL_SIZE[] = {10, 11, 12, 13}; +const int32_t HDMX_MAX_WIDTH[] = {5, 6, 7, 7}; + +bool TestReadingHdmxTable() { + FontFactoryPtr factory; + factory.Attach(FontFactory::GetInstance()); + FontArray font_array; + LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array); + FontPtr font = font_array[0]; + + HorizontalDeviceMetricsTablePtr hdmx_table = + down_cast<HorizontalDeviceMetricsTable*>(font->GetTable(Tag::hdmx)); + + EXPECT_FALSE(hdmx_table == NULL); + + EXPECT_EQ(hdmx_table->Version(), HDMX_VERSION); + EXPECT_EQ(hdmx_table->NumRecords(), HDMX_NUM_RECORDS); + EXPECT_EQ(hdmx_table->RecordSize(), HDMX_RECORD_SIZE); + + for (int32_t i = 0; i < HDMX_NUM_RECORDS; ++i) { + EXPECT_EQ(hdmx_table->PixelSize(i), HDMX_PIXEL_SIZE[i]); + EXPECT_EQ(hdmx_table->MaxWidth(i), HDMX_MAX_WIDTH[i]); + } + + EXPECT_EQ(hdmx_table->Width(0, 0), HDMX_MAX_WIDTH[0]); + EXPECT_EQ(hdmx_table->Width(0, 19), HDMX_MAX_WIDTH[0]); + EXPECT_EQ(hdmx_table->Width(0, 623), HDMX_MAX_WIDTH[0]); + EXPECT_EQ(hdmx_table->Width(1, 0), HDMX_MAX_WIDTH[1]); + EXPECT_EQ(hdmx_table->Width(1, 19), HDMX_MAX_WIDTH[1]); + EXPECT_EQ(hdmx_table->Width(1, 623), HDMX_MAX_WIDTH[1]); + EXPECT_EQ(hdmx_table->Width(2, 0), HDMX_MAX_WIDTH[2]); + EXPECT_EQ(hdmx_table->Width(2, 19), HDMX_MAX_WIDTH[2]); + EXPECT_EQ(hdmx_table->Width(2, 623), HDMX_MAX_WIDTH[2]); + EXPECT_EQ(hdmx_table->Width(3, 0), HDMX_MAX_WIDTH[3]); + EXPECT_EQ(hdmx_table->Width(3, 19), HDMX_MAX_WIDTH[3]); + EXPECT_EQ(hdmx_table->Width(3, 623), HDMX_MAX_WIDTH[3]); + +#if defined(SFNTLY_NO_EXCEPTION) + EXPECT_EQ(hdmx_table->PixelSize(4), -1); + EXPECT_EQ(hdmx_table->PixelSize(-1), -1); + EXPECT_EQ(hdmx_table->MaxWidth(4), -1); + EXPECT_EQ(hdmx_table->MaxWidth(-1), -1); + EXPECT_EQ(hdmx_table->Width(0, 624), -1); + EXPECT_EQ(hdmx_table->Width(1, -1), -1); + EXPECT_EQ(hdmx_table->Width(-1, 0), -1); + EXPECT_EQ(hdmx_table->Width(-1, -1), -1); +#endif + return true; +} + +} // namespace sfntly + +TEST(HdmxTable, All) { + ASSERT_TRUE(sfntly::TestReadingHdmxTable()); +} |