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/font_factory.h"
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/memory_input_stream.h"
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/memory_output_stream.h"
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_data.h"
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_font_utils.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/serialization_test.h"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestSerialization() {
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory1, factory2, factory3;
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory1.Attach(FontFactory::GetInstance());
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray font_array;
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFont(SAMPLE_TTF_FILE, factory1, &font_array);
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr original = font_array[0];
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory2.Attach(FontFactory::GetInstance());
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array;
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BuilderForFontFile(SAMPLE_TTF_FILE, factory2, &font_builder_array);
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder = font_builder_array[0];
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr intermediate;
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  intermediate.Attach(font_builder->Build());
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryOutputStream os;
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory2->SerializeFont(intermediate, &os);
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory3.Attach(FontFactory::GetInstance());
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray new_font_array;
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryInputStream is;
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  is.Attach(os.Get(), os.Size());
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory3->LoadFonts(&is, &new_font_array);
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr serialized = new_font_array[0];
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check number of tables
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(original->num_tables(), serialized->num_tables());
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check if same set of tables
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const TableMap* original_tables = original->GetTableMap();
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const TableMap* serialized_tables = serialized->GetTableMap();
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(original_tables->size(), serialized_tables->size());
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  TableMap::const_iterator not_found = serialized_tables->end();
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (TableMap::const_iterator b = original_tables->begin(),
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                e = original_tables->end(); b != e; ++b) {
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // TODO(arthurhsu): check cmap equivalence
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check checksum equivalence
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      TablePtr original_table = original->GetTable(TTF_KNOWN_TAGS[i]);
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      TablePtr serialized_table = serialized->GetTable(TTF_KNOWN_TAGS[i]);
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(original_table->CalculatedChecksum(),
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              serialized_table->CalculatedChecksum());
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    if (TTF_KNOWN_TAGS[i] == Tag::hhea) {
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      EXPECT_TRUE(VerifyHHEA(original_table, serialized_table));
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::glyf) {
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyGLYF(original_table, serialized_table));
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::hmtx) {
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyHMTX(original_table, serialized_table));
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::loca) {
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyLOCA(original_table, serialized_table));
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::maxp) {
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyMAXP(original_table, serialized_table));
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::name) {
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyNAME(original_table, serialized_table));
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else if (TTF_KNOWN_TAGS[i] == Tag::OS_2) {
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        EXPECT_TRUE(VerifyOS_2(original_table, serialized_table));
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestSerializationBitmap() {
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory1, factory2, factory3;
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory1.Attach(FontFactory::GetInstance());
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray font_array;
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFont(SAMPLE_BITMAP_FONT, factory1, &font_array);
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr original = font_array[0];
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory2.Attach(FontFactory::GetInstance());
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array;
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BuilderForFontFile(SAMPLE_BITMAP_FONT, factory2, &font_builder_array);
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder = font_builder_array[0];
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr intermediate;
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  intermediate.Attach(font_builder->Build());
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryOutputStream os;
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory2->SerializeFont(intermediate, &os);
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory3.Attach(FontFactory::GetInstance());
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray new_font_array;
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryInputStream is;
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  is.Attach(os.Get(), os.Size());
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory3->LoadFonts(&is, &new_font_array);
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr serialized = new_font_array[0];
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check number of tables
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(original->num_tables(), serialized->num_tables());
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check if same set of tables
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const TableMap* original_tables = original->GetTableMap();
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const TableMap* serialized_tables = serialized->GetTableMap();
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(original_tables->size(), serialized_tables->size());
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  TableMap::const_iterator not_found = serialized_tables->end();
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (TableMap::const_iterator b = original_tables->begin(),
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                e = original_tables->end(); b != e; ++b) {
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Check checksum equivalence
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (size_t i = 0; i < SAMPLE_BITMAP_KNOWN_TAGS; ++i) {
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      TablePtr original_table = original->GetTable(BITMAP_KNOWN_TAGS[i]);
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      TablePtr serialized_table = serialized->GetTable(BITMAP_KNOWN_TAGS[i]);
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(original_table->CalculatedChecksum(),
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              serialized_table->CalculatedChecksum());
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(Serialization, Simple) {
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestSerialization());
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(Serialization, Bitmap) {
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestSerializationBitmap());
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
152