summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51>2011-11-15 19:34:35 +0000
committerarthurhsu@google.com <arthurhsu@google.com@672e30a5-4c29-85ac-ac6d-611c735e0a51>2011-11-15 19:34:35 +0000
commita7acde600e171e08e75138318308de83f38b3097 (patch)
tree00c68d6768025720b4e8cc0e719099f1fd63ead7
parent144e5cb2b372c30d8a4b90267b52646368dd89fc (diff)
downloadsrc-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.cc17
-rw-r--r--sfntly/table/core/horizontal_device_metrics_table.cc124
-rw-r--r--sfntly/table/core/horizontal_device_metrics_table.h82
-rw-r--r--sfntly/table/table.cc21
-rw-r--r--test/hdmx_test.cc82
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());
+}