130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*
230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved.
330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License");
530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License.
630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at
730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *      http://www.apache.org/licenses/LICENSE-2.0
930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software
1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS,
1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and
1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License.
1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */
1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "gtest/gtest.h"
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font.h"
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/file_input_stream.h"
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/memory_input_stream.h"
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/memory_output_stream.h"
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/ebdt_table.h"
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/eblc_table.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/index_sub_table_format3.h"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/index_sub_table_format4.h"
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_data.h"
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_font_utils.h"
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t NUM_STRIKES = 4;
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_ARRAY_OFFSET = 0xc8;
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_INDEX_TABLE_SIZE = 0x4f4;
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_NUM_INDEX_TABLES = 1;
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_COLOR_REF = 0;
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_START_GLYPH_INDEX = 0;
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_END_GLYPH_INDEX = 623;
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_PPEM_X = 10;
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_PPEM_Y = 10;
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_BIT_DEPTH = 1;
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE1_FLAGS = 0x01;
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE4_SUB1_INDEX_FORMAT = 3;
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE4_SUB1_IMAGE_FORMAT = 1;
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE4_SUB1_IMAGE_DATA_OFFSET = 0x00005893;
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE4_SUB1_GLYPH_OFFSET[] = {
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    0x00005893, 0x00005898, 0x0000589d, 0x000058a2, 0x000058a7,
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    0x000058b2, 0x000058c2, 0x000058d0, 0x000058de, 0x000058e6 };
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t NUM_STRIKE4_SUB1_GLYPH_OFFSET = 10;
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t STRIKE4_SUB1_GLYPH2_LENGTH = 0x58a2 - 0x589d;
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool CommonReadingTest(Font* raw_font) {
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr font = raw_font;
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EbdtTablePtr bitmap_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(bitmap_loca == NULL);
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(bitmap_table == NULL);
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES);
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Strike 1
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(strike1 == NULL);
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET);
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES);
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF);
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->PpemX(), STRIKE1_PPEM_X);
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->PpemY(), STRIKE1_PPEM_Y);
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->BitDepth(), STRIKE1_BIT_DEPTH);
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->FlagsAsInt(), STRIKE1_FLAGS);
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Strike 4
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // In this test font, all strikes and all subtables have same glyphs.
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(strike4 == NULL);
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike4->StartGlyphIndex(), STRIKE1_START_GLYPH_INDEX);
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike4->EndGlyphIndex(), STRIKE1_END_GLYPH_INDEX);
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(sub1 == NULL);
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(sub1->image_format(), STRIKE4_SUB1_IMAGE_FORMAT);
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(sub1->first_glyph_index(), STRIKE1_START_GLYPH_INDEX);
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(sub1->last_glyph_index(), STRIKE1_END_GLYPH_INDEX);
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(sub1->image_data_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (int32_t i = 0; i < NUM_STRIKE4_SUB1_GLYPH_OFFSET; ++i) {
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      EXPECT_EQ(sub1->GlyphOffset(i), STRIKE4_SUB1_GLYPH_OFFSET[i]);
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestReadingBitmapTable() {
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory;
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory.Attach(FontFactory::GetInstance());
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray font_array;
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFont(SAMPLE_BITMAP_FONT, factory, &font_array);
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr font = font_array[0];
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_TRUE(CommonReadingTest(font));
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EblcTablePtr bitmap_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTablePtr sub1 = strike4->GetIndexSubTable(0);
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike1->IndexTableSize(), STRIKE1_INDEX_TABLE_SIZE);
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(sub1->index_format(), STRIKE4_SUB1_INDEX_FORMAT);
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Strike 4 Index Sub Table 1 is a Format 3
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTableFormat3Ptr sub3 =
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(sub3 == NULL);
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapGlyphInfoPtr info;
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  info.Attach(sub3->GlyphInfo(2));
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(info->glyph_id(), 2);
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(info->block_offset(), STRIKE4_SUB1_IMAGE_DATA_OFFSET);
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(info->start_offset(),
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            STRIKE4_SUB1_GLYPH_OFFSET[2] - STRIKE4_SUB1_GLYPH_OFFSET[0]);
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(info->format(), STRIKE4_SUB1_IMAGE_FORMAT);
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(info->length(), STRIKE4_SUB1_GLYPH2_LENGTH);
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Function in subset_impl.cc
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunextern
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca);
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestIndexFormatConversion() {
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory;
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory.Attach(FontFactory::GetInstance());
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray builder_array;
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BuilderForFontFile(SAMPLE_BITMAP_FONT, factory, &builder_array);
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder;
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  font_builder = builder_array[0];
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EblcTableBuilderPtr eblc_builder =
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<EblcTable::Builder*>(font_builder->GetTableBuilder(Tag::EBLC));
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapLocaList new_loca;
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  eblc_builder->GenerateLocaList(&new_loca);
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  SubsetEBLC(eblc_builder, new_loca);  // Format 3 -> 4
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr new_font;
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  new_font.Attach(font_builder->Build());
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Serialize and reload the serialized font.
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryOutputStream os;
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->SerializeFont(new_font, &os);
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  SerializeToFile(&os, "anon-mod.ttf");
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryInputStream is;
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  is.Attach(os.Get(), os.Size());
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray font_array;
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->LoadFonts(&is, &font_array);
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  new_font = font_array[0];
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_TRUE(CommonReadingTest(new_font));
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Strike 4 Index Sub Table 1 is a Format 4
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EblcTablePtr bitmap_loca =
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<EblcTable*>(new_font->GetTable(Tag::EBLC));
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr strike4 = bitmap_loca->GetBitmapSizeTable(3);
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTableFormat4Ptr sub4 =
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<IndexSubTableFormat4*>(strike4->GetIndexSubTable(0));
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(sub4 == NULL);
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // And this subtable shall have exactly the same offset as original table
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // since no subsetting happens.
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray original_font_array;
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFont(SAMPLE_BITMAP_FONT, factory, &original_font_array);
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr font = original_font_array[0];
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(font == NULL);
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EblcTablePtr original_loca = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(original_loca == NULL);
18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTablePtr original_strike4 = bitmap_loca->GetBitmapSizeTable(3);
18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(original_strike4 == NULL);
18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  IndexSubTableFormat3Ptr sub3 =
18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<IndexSubTableFormat3*>(strike4->GetIndexSubTable(0));
18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_FALSE(sub3 == NULL);
18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike4->StartGlyphIndex(), original_strike4->StartGlyphIndex());
18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(strike4->EndGlyphIndex(), original_strike4->EndGlyphIndex());
18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (int32_t i = strike4->StartGlyphIndex();
18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               i <= strike4->EndGlyphIndex(); ++i) {
18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    BitmapGlyphInfoPtr info, original_info;
19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    info.Attach(sub4->GlyphInfo(i));
19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    original_info.Attach(sub3->GlyphInfo(i));
19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(info->format(), original_info->format());
19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(info->glyph_id(), original_info->glyph_id());
19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(info->length(), original_info->length());
19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(info->offset(), original_info->offset());
19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(BitmapTable, Reading) {
20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestReadingBitmapTable());
20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(BitmapTable, IndexFormatConversion) {
20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestIndexFormatConversion());
20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
210