Home | History | Annotate | Download | only in test
      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 "gtest/gtest.h"
     18 #include "sfntly/font.h"
     19 #include "sfntly/port/file_input_stream.h"
     20 #include "sfntly/port/memory_input_stream.h"
     21 #include "sfntly/port/memory_output_stream.h"
     22 #include "sfntly/table/bitmap/ebdt_table.h"
     23 #include "sfntly/table/bitmap/eblc_table.h"
     24 #include "sfntly/table/bitmap/index_sub_table_format3.h"
     25 #include "sfntly/table/bitmap/index_sub_table_format4.h"
     26 #include "test/test_data.h"
     27 #include "test/test_font_utils.h"
     28 
     29 namespace sfntly {
     30 
     31 const int32_t NUM_STRIKES = 4;
     32 const int32_t STRIKE1_ARRAY_OFFSET = 0xc8;
     33 const int32_t STRIKE1_INDEX_TABLE_SIZE = 0x4f4;
     34 const int32_t STRIKE1_NUM_INDEX_TABLES = 1;
     35 const int32_t STRIKE1_COLOR_REF = 0;
     36 const int32_t STRIKE1_START_GLYPH_INDEX = 0;
     37 const int32_t STRIKE1_END_GLYPH_INDEX = 623;
     38 const int32_t STRIKE1_PPEM_X = 10;
     39 const int32_t STRIKE1_PPEM_Y = 10;
     40 const int32_t STRIKE1_BIT_DEPTH = 1;
     41 const int32_t STRIKE1_FLAGS = 0x01;
     42 
     43 const int32_t STRIKE4_SUB1_INDEX_FORMAT = 3;
     44 const int32_t STRIKE4_SUB1_IMAGE_FORMAT = 1;
     45 const int32_t STRIKE4_SUB1_IMAGE_DATA_OFFSET = 0x00005893;
     46 const int32_t STRIKE4_SUB1_GLYPH_OFFSET[] = {
     47     0x00005893, 0x00005898, 0x0000589d, 0x000058a2, 0x000058a7,
     48     0x000058b2, 0x000058c2, 0x000058d0, 0x000058de, 0x000058e6 };
     49 const int32_t NUM_STRIKE4_SUB1_GLYPH_OFFSET = 10;
     50 const int32_t STRIKE4_SUB1_GLYPH2_LENGTH = 0x58a2 - 0x589d;
     51 
     52 bool CommonReadingTest(Font* raw_font) {
     53   FontPtr font = raw_font;
     54 
     55   EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
     56   EbdtTablePtr bitmap_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
     57 
     58   EXPECT_FALSE(bitmap_loca == NULL);
     59   EXPECT_FALSE(bitmap_table == NULL);
     60 
     61   EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES);
     62 
     63   // Strike 1
     64   BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
     65   EXPECT_FALSE(strike1 == NULL);
     66   EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET);
     67   EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES);
     68   EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF);
     69   EXPECT_EQ(strike1->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
     70   EXPECT_EQ(strike1->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
     71   EXPECT_EQ(strike1->PpemX(), STRIKE1_PPEM_X);
     72   EXPECT_EQ(strike1->PpemY(), STRIKE1_PPEM_Y);
     73   EXPECT_EQ(strike1->BitDepth(), STRIKE1_BIT_DEPTH);
     74   EXPECT_EQ(strike1->FlagsAsInt(), STRIKE1_FLAGS);
     75 
     76   // Strike 4
     77   // In this test font, all strikes and all subtables have same glyphs.
     78   BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
     79   EXPECT_FALSE(strike4 == NULL);
     80   EXPECT_EQ(strike4->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
     81   EXPECT_EQ(strike4->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
     82   IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
     83   EXPECT_FALSE(sub1 == NULL);
     84   EXPECT_EQ(sub1->image_format(), STRIKE4_SUB1_IMAGE_FORMAT);
     85   EXPECT_EQ(sub1->first_glyph_index(), STRIKE1_START_GLYPH_INDEX);
     86   EXPECT_EQ(sub1->last_glyph_index(), STRIKE1_END_GLYPH_INDEX);
     87   EXPECT_EQ(sub1->image_data_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
     88 
     89   for (int32_t i = 0; i < NUM_STRIKE4_SUB1_GLYPH_OFFSET; ++i) {
     90       EXPECT_EQ(sub1->GlyphOffset(i), STRIKE4_SUB1_GLYPH_OFFSET[i]);
     91   }
     92   return true;
     93 }
     94 
     95 bool TestReadingBitmapTable() {
     96   FontFactoryPtr factory;
     97   factory.Attach(FontFactory::GetInstance());
     98   FontArray font_array;
     99   LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array);
    100   FontPtr font = font_array[0];
    101   EXPECT_TRUE(CommonReadingTest(font));
    102 
    103   EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
    104   BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
    105   BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
    106   IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
    107 
    108   EXPECT_EQ(strike1->IndexTableSize(), STRIKE1_INDEX_TABLE_SIZE);
    109   EXPECT_EQ(sub1->index_format(), STRIKE4_SUB1_INDEX_FORMAT);
    110 
    111   // Strike 4 Index Sub Table 1 is a Format 3
    112   IndexSubTableFormat3Ptr sub3 =
    113       down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
    114   EXPECT_FALSE(sub3 == NULL);
    115   BitmapGlyphInfoPtr info;
    116   info.Attach(sub3->GlyphInfo(2));
    117   EXPECT_EQ(info->glyph_id(), 2);
    118   EXPECT_EQ(info->block_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
    119   EXPECT_EQ(info->start_offset(),
    120             STRIKE4_SUB1_GLYPH_OFFSET[2] - STRIKE4_SUB1_GLYPH_OFFSET[0]);
    121   EXPECT_EQ(info->format(), STRIKE4_SUB1_IMAGE_FORMAT);
    122   EXPECT_EQ(info->length(), STRIKE4_SUB1_GLYPH2_LENGTH);
    123 
    124   return true;
    125 }
    126 
    127 // Function in subset_impl.cc
    128 extern
    129 void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca);
    130 
    131 bool TestIndexFormatConversion() {
    132   FontFactoryPtr factory;
    133   factory.Attach(FontFactory::GetInstance());
    134   FontBuilderArray builder_array;
    135   BuilderForFontFile(SAMPLE_BITMAP_FONT, factory, &builder_array);
    136 
    137   FontBuilderPtr font_builder;
    138   font_builder = builder_array[0];
    139   EblcTableBuilderPtr eblc_builder =
    140       down_cast<EblcTable::Builder*>(font_builder->GetTableBuilder(Tag::EBLC));
    141   BitmapLocaList new_loca;
    142   eblc_builder->GenerateLocaList(&new_loca);
    143   SubsetEBLC(eblc_builder, new_loca);  // Format 3 -> 4
    144 
    145   FontPtr new_font;
    146   new_font.Attach(font_builder->Build());
    147 
    148   // Serialize and reload the serialized font.
    149   MemoryOutputStream os;
    150   factory->SerializeFont(new_font, &os);
    151 
    152 #if defined (SFNTLY_DEBUG_BITMAP)
    153   SerializeToFile(&os, "anon-mod.ttf");
    154 #endif
    155 
    156   MemoryInputStream is;
    157   is.Attach(os.Get(), os.Size());
    158   FontArray font_array;
    159   factory->LoadFonts(&is, &font_array);
    160   new_font = font_array[0];
    161 
    162   EXPECT_TRUE(CommonReadingTest(new_font));
    163 
    164   // Strike 4 Index Sub Table 1 is a Format 4
    165   EblcTablePtr bitmap_loca =
    166       down_cast<EblcTable*>(new_font->GetTable(Tag::EBLC));
    167   BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
    168   IndexSubTableFormat4Ptr sub4 =
    169       down_cast<IndexSubTableFormat4*>(strike4->GetIndexSubTable(0));
    170   EXPECT_FALSE(sub4 == NULL);
    171 
    172   // And this subtable shall have exactly the same offset as original table
    173   // since no subsetting happens.
    174   FontArray original_font_array;
    175   LoadFont(SAMPLE_BITMAP_FONT, factory, &original_font_array);
    176   FontPtr font = original_font_array[0];
    177   EXPECT_FALSE(font == NULL);
    178   EblcTablePtr original_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
    179   EXPECT_FALSE(original_loca == NULL);
    180   BitmapSizeTablePtr original_strike4 = bitmap_loca->GetBitmapSizeTable(3);
    181   EXPECT_FALSE(original_strike4 == NULL);
    182   IndexSubTableFormat3Ptr sub3 =
    183       down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
    184   EXPECT_FALSE(sub3 == NULL);
    185   EXPECT_EQ(strike4->StartGlyphIndex(), original_strike4->StartGlyphIndex());
    186   EXPECT_EQ(strike4->EndGlyphIndex(), original_strike4->EndGlyphIndex());
    187   for (int32_t i = strike4->StartGlyphIndex();
    188                i <= strike4->EndGlyphIndex(); ++i) {
    189     BitmapGlyphInfoPtr info, original_info;
    190     info.Attach(sub4->GlyphInfo(i));
    191     original_info.Attach(sub3->GlyphInfo(i));
    192     EXPECT_EQ(info->format(), original_info->format());
    193     EXPECT_EQ(info->glyph_id(), original_info->glyph_id());
    194     EXPECT_EQ(info->length(), original_info->length());
    195     EXPECT_EQ(info->offset(), original_info->offset());
    196   }
    197 
    198   return true;
    199 }
    200 
    201 }  // namespace sfntly
    202 
    203 TEST(BitmapTable, Reading) {
    204   ASSERT_TRUE(sfntly::TestReadingBitmapTable());
    205 }
    206 
    207 TEST(BitmapTable, IndexFormatConversion) {
    208   ASSERT_TRUE(sfntly::TestIndexFormatConversion());
    209 }
    210