| /* |
| * 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/port/file_input_stream.h" |
| #include "sfntly/port/memory_input_stream.h" |
| #include "sfntly/port/memory_output_stream.h" |
| #include "sfntly/table/bitmap/ebdt_table.h" |
| #include "sfntly/table/bitmap/eblc_table.h" |
| #include "sfntly/table/bitmap/index_sub_table_format3.h" |
| #include "sfntly/table/bitmap/index_sub_table_format4.h" |
| #include "test/test_data.h" |
| #include "test/test_font_utils.h" |
| |
| namespace sfntly { |
| |
| const int32_t NUM_STRIKES = 4; |
| const int32_t STRIKE1_ARRAY_OFFSET = 0xc8; |
| const int32_t STRIKE1_INDEX_TABLE_SIZE = 0x4f4; |
| const int32_t STRIKE1_NUM_INDEX_TABLES = 1; |
| const int32_t STRIKE1_COLOR_REF = 0; |
| const int32_t STRIKE1_START_GLYPH_INDEX = 0; |
| const int32_t STRIKE1_END_GLYPH_INDEX = 623; |
| const int32_t STRIKE1_PPEM_X = 10; |
| const int32_t STRIKE1_PPEM_Y = 10; |
| const int32_t STRIKE1_BIT_DEPTH = 1; |
| const int32_t STRIKE1_FLAGS = 0x01; |
| |
| const int32_t STRIKE4_SUB1_INDEX_FORMAT = 3; |
| const int32_t STRIKE4_SUB1_IMAGE_FORMAT = 1; |
| const int32_t STRIKE4_SUB1_IMAGE_DATA_OFFSET = 0x00005893; |
| const int32_t STRIKE4_SUB1_GLYPH_OFFSET[] = { |
| 0x00005893, 0x00005898, 0x0000589d, 0x000058a2, 0x000058a7, |
| 0x000058b2, 0x000058c2, 0x000058d0, 0x000058de, 0x000058e6 }; |
| const int32_t NUM_STRIKE4_SUB1_GLYPH_OFFSET = 10; |
| const int32_t STRIKE4_SUB1_GLYPH2_LENGTH = 0x58a2 - 0x589d; |
| |
| bool CommonReadingTest(Font* raw_font) { |
| FontPtr font = raw_font; |
| |
| EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC)); |
| EbdtTablePtr bitmap_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT)); |
| |
| EXPECT_FALSE(bitmap_loca == NULL); |
| EXPECT_FALSE(bitmap_table == NULL); |
| |
| EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES); |
| |
| // Strike 1 |
| BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0); |
| EXPECT_FALSE(strike1 == NULL); |
| EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET); |
| EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES); |
| EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF); |
| EXPECT_EQ(strike1->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX); |
| EXPECT_EQ(strike1->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX); |
| EXPECT_EQ(strike1->PpemX(), STRIKE1_PPEM_X); |
| EXPECT_EQ(strike1->PpemY(), STRIKE1_PPEM_Y); |
| EXPECT_EQ(strike1->BitDepth(), STRIKE1_BIT_DEPTH); |
| EXPECT_EQ(strike1->FlagsAsInt(), STRIKE1_FLAGS); |
| |
| // Strike 4 |
| // In this test font, all strikes and all subtables have same glyphs. |
| BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3); |
| EXPECT_FALSE(strike4 == NULL); |
| EXPECT_EQ(strike4->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX); |
| EXPECT_EQ(strike4->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX); |
| IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0); |
| EXPECT_FALSE(sub1 == NULL); |
| EXPECT_EQ(sub1->image_format(), STRIKE4_SUB1_IMAGE_FORMAT); |
| EXPECT_EQ(sub1->first_glyph_index(), STRIKE1_START_GLYPH_INDEX); |
| EXPECT_EQ(sub1->last_glyph_index(), STRIKE1_END_GLYPH_INDEX); |
| EXPECT_EQ(sub1->image_data_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET); |
| |
| for (int32_t i = 0; i < NUM_STRIKE4_SUB1_GLYPH_OFFSET; ++i) { |
| EXPECT_EQ(sub1->GlyphOffset(i), STRIKE4_SUB1_GLYPH_OFFSET[i]); |
| } |
| return true; |
| } |
| |
| bool TestReadingBitmapTable() { |
| FontFactoryPtr factory; |
| factory.Attach(FontFactory::GetInstance()); |
| FontArray font_array; |
| LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array); |
| FontPtr font = font_array[0]; |
| EXPECT_TRUE(CommonReadingTest(font)); |
| |
| EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC)); |
| BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0); |
| BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3); |
| IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0); |
| |
| EXPECT_EQ(strike1->IndexTableSize(), STRIKE1_INDEX_TABLE_SIZE); |
| EXPECT_EQ(sub1->index_format(), STRIKE4_SUB1_INDEX_FORMAT); |
| |
| // Strike 4 Index Sub Table 1 is a Format 3 |
| IndexSubTableFormat3Ptr sub3 = |
| down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0)); |
| EXPECT_FALSE(sub3 == NULL); |
| BitmapGlyphInfoPtr info; |
| info.Attach(sub3->GlyphInfo(2)); |
| EXPECT_EQ(info->glyph_id(), 2); |
| EXPECT_EQ(info->block_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET); |
| EXPECT_EQ(info->start_offset(), |
| STRIKE4_SUB1_GLYPH_OFFSET[2] - STRIKE4_SUB1_GLYPH_OFFSET[0]); |
| EXPECT_EQ(info->format(), STRIKE4_SUB1_IMAGE_FORMAT); |
| EXPECT_EQ(info->length(), STRIKE4_SUB1_GLYPH2_LENGTH); |
| |
| return true; |
| } |
| |
| // Function in subset_impl.cc |
| extern |
| void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca); |
| |
| bool TestIndexFormatConversion() { |
| FontFactoryPtr factory; |
| factory.Attach(FontFactory::GetInstance()); |
| FontBuilderArray builder_array; |
| BuilderForFontFile(SAMPLE_BITMAP_FONT, factory, &builder_array); |
| |
| FontBuilderPtr font_builder; |
| font_builder = builder_array[0]; |
| EblcTableBuilderPtr eblc_builder = |
| down_cast<EblcTable::Builder*>(font_builder->GetTableBuilder(Tag::EBLC)); |
| BitmapLocaList new_loca; |
| eblc_builder->GenerateLocaList(&new_loca); |
| SubsetEBLC(eblc_builder, new_loca); // Format 3 -> 4 |
| |
| FontPtr new_font; |
| new_font.Attach(font_builder->Build()); |
| |
| // Serialize and reload the serialized font. |
| MemoryOutputStream os; |
| factory->SerializeFont(new_font, &os); |
| |
| #if defined (SFNTLY_DEBUG_BITMAP) |
| SerializeToFile(&os, "anon-mod.ttf"); |
| #endif |
| |
| MemoryInputStream is; |
| is.Attach(os.Get(), os.Size()); |
| FontArray font_array; |
| factory->LoadFonts(&is, &font_array); |
| new_font = font_array[0]; |
| |
| EXPECT_TRUE(CommonReadingTest(new_font)); |
| |
| // Strike 4 Index Sub Table 1 is a Format 4 |
| EblcTablePtr bitmap_loca = |
| down_cast<EblcTable*>(new_font->GetTable(Tag::EBLC)); |
| BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3); |
| IndexSubTableFormat4Ptr sub4 = |
| down_cast<IndexSubTableFormat4*>(strike4->GetIndexSubTable(0)); |
| EXPECT_FALSE(sub4 == NULL); |
| |
| // And this subtable shall have exactly the same offset as original table |
| // since no subsetting happens. |
| FontArray original_font_array; |
| LoadFont(SAMPLE_BITMAP_FONT, factory, &original_font_array); |
| FontPtr font = original_font_array[0]; |
| EXPECT_FALSE(font == NULL); |
| EblcTablePtr original_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC)); |
| EXPECT_FALSE(original_loca == NULL); |
| BitmapSizeTablePtr original_strike4 = bitmap_loca->GetBitmapSizeTable(3); |
| EXPECT_FALSE(original_strike4 == NULL); |
| IndexSubTableFormat3Ptr sub3 = |
| down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0)); |
| EXPECT_FALSE(sub3 == NULL); |
| EXPECT_EQ(strike4->StartGlyphIndex(), original_strike4->StartGlyphIndex()); |
| EXPECT_EQ(strike4->EndGlyphIndex(), original_strike4->EndGlyphIndex()); |
| for (int32_t i = strike4->StartGlyphIndex(); |
| i <= strike4->EndGlyphIndex(); ++i) { |
| BitmapGlyphInfoPtr info, original_info; |
| info.Attach(sub4->GlyphInfo(i)); |
| original_info.Attach(sub3->GlyphInfo(i)); |
| EXPECT_EQ(info->format(), original_info->format()); |
| EXPECT_EQ(info->glyph_id(), original_info->glyph_id()); |
| EXPECT_EQ(info->length(), original_info->length()); |
| EXPECT_EQ(info->offset(), original_info->offset()); |
| } |
| |
| return true; |
| } |
| |
| } // namespace sfntly |
| |
| TEST(BitmapTable, Reading) { |
| ASSERT_TRUE(sfntly::TestReadingBitmapTable()); |
| } |
| |
| TEST(BitmapTable, IndexFormatConversion) { |
| ASSERT_TRUE(sfntly::TestIndexFormatConversion()); |
| } |