1deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com/*
2deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com *
4deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * you may not use this file except in compliance with the License.
6deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * You may obtain a copy of the License at
7deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com *
8deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com *
10deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * See the License for the specific language governing permissions and
14deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com * limitations under the License.
15deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com */
16deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
17deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com#include "gtest/gtest.h"
18deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com#include "sfntly/font.h"
19deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com#include "sfntly/font_factory.h"
20b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com#include "sfntly/port/memory_input_stream.h"
21b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com#include "sfntly/port/memory_output_stream.h"
22deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com#include "test/test_data.h"
23deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com#include "test/test_font_utils.h"
24f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com#include "test/serialization_test.h"
25deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
26deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.comnamespace sfntly {
27deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
28deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.combool TestSerialization() {
29deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontFactoryPtr factory1, factory2, factory3;
30deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  factory1.Attach(FontFactory::GetInstance());
31deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontArray font_array;
32deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  LoadFont(SAMPLE_TTF_FILE, factory1, &font_array);
33deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontPtr original = font_array[0];
34deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
35deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  factory2.Attach(FontFactory::GetInstance());
36deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontBuilderArray font_builder_array;
37deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  BuilderForFontFile(SAMPLE_TTF_FILE, factory2, &font_builder_array);
38deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontBuilderPtr font_builder = font_builder_array[0];
39deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
40deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontPtr intermediate;
41deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  intermediate.Attach(font_builder->Build());
42deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  MemoryOutputStream os;
43deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  factory2->SerializeFont(intermediate, &os);
44deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
45deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  factory3.Attach(FontFactory::GetInstance());
46deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontArray new_font_array;
47b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  MemoryInputStream is;
48b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  is.Attach(os.Get(), os.Size());
49b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  factory3->LoadFonts(&is, &new_font_array);
50deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  FontPtr serialized = new_font_array[0];
51deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
52deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  // Check number of tables
53deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  EXPECT_EQ(original->num_tables(), serialized->num_tables());
54deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
55deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  // Check if same set of tables
56b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  const TableMap* original_tables = original->GetTableMap();
57b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  const TableMap* serialized_tables = serialized->GetTableMap();
58deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  EXPECT_EQ(original_tables->size(), serialized_tables->size());
59b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  TableMap::const_iterator not_found = serialized_tables->end();
60b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com  for (TableMap::const_iterator b = original_tables->begin(),
61b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com                                e = original_tables->end(); b != e; ++b) {
62deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
63deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  }
64deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
65deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  // TODO(arthurhsu): check cmap equivalence
66deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  // Check checksum equivalence
67deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
68deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com      TablePtr original_table = original->GetTable(TTF_KNOWN_TAGS[i]);
69deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com      TablePtr serialized_table = serialized->GetTable(TTF_KNOWN_TAGS[i]);
70deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com    EXPECT_EQ(original_table->CalculatedChecksum(),
71deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com              serialized_table->CalculatedChecksum());
72b54cce09c1fc2b09e2adae43d7eb017b47b0cccfarthurhsu@google.com    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
73f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com
74f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    if (TTF_KNOWN_TAGS[i] == Tag::hhea) {
75f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com      EXPECT_TRUE(VerifyHHEA(original_table, serialized_table));
76f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::glyf) {
77f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyGLYF(original_table, serialized_table));
78f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::hmtx) {
79f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyHMTX(original_table, serialized_table));
80f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::loca) {
81f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyLOCA(original_table, serialized_table));
82f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::maxp) {
83f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyMAXP(original_table, serialized_table));
84f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::name) {
85f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyNAME(original_table, serialized_table));
86f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    } else if (TTF_KNOWN_TAGS[i] == Tag::OS_2) {
87f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com        EXPECT_TRUE(VerifyOS_2(original_table, serialized_table));
88f7c13bf6ff210e3c018971a6f219bb626ae00378arthurhsu@google.com    }
89deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  }
90deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
91deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  return true;
92deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com}
93deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
9453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.combool TestSerializationBitmap() {
9553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontFactoryPtr factory1, factory2, factory3;
9653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  factory1.Attach(FontFactory::GetInstance());
9753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontArray font_array;
9853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  LoadFont(SAMPLE_BITMAP_FONT, factory1, &font_array);
9953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontPtr original = font_array[0];
10053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
10153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  factory2.Attach(FontFactory::GetInstance());
10253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontBuilderArray font_builder_array;
10353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  BuilderForFontFile(SAMPLE_BITMAP_FONT, factory2, &font_builder_array);
10453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontBuilderPtr font_builder = font_builder_array[0];
10553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
10653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontPtr intermediate;
10753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  intermediate.Attach(font_builder->Build());
10853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  MemoryOutputStream os;
10953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  factory2->SerializeFont(intermediate, &os);
11053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
11153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  factory3.Attach(FontFactory::GetInstance());
11253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontArray new_font_array;
11353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  MemoryInputStream is;
11453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  is.Attach(os.Get(), os.Size());
11553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  factory3->LoadFonts(&is, &new_font_array);
11653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  FontPtr serialized = new_font_array[0];
11753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
11853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  // Check number of tables
11953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  EXPECT_EQ(original->num_tables(), serialized->num_tables());
12053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
12153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  // Check if same set of tables
12253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  const TableMap* original_tables = original->GetTableMap();
12353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  const TableMap* serialized_tables = serialized->GetTableMap();
12453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  EXPECT_EQ(original_tables->size(), serialized_tables->size());
12553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  TableMap::const_iterator not_found = serialized_tables->end();
12653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  for (TableMap::const_iterator b = original_tables->begin(),
12753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com                                e = original_tables->end(); b != e; ++b) {
12853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    EXPECT_TRUE((serialized_tables->find(b->first) != not_found));
12953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  }
13053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
13153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  // Check checksum equivalence
13253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  for (size_t i = 0; i < SAMPLE_BITMAP_KNOWN_TAGS; ++i) {
13353847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com      TablePtr original_table = original->GetTable(BITMAP_KNOWN_TAGS[i]);
13453847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com      TablePtr serialized_table = serialized->GetTable(BITMAP_KNOWN_TAGS[i]);
13553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    EXPECT_EQ(original_table->CalculatedChecksum(),
13653847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com              serialized_table->CalculatedChecksum());
13753847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com    EXPECT_EQ(original_table->DataLength(), serialized_table->DataLength());
13853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  }
13953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
14053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  return true;
14153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com}
14253847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
143deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com}  // namespace sfntly
144deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com
14553847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.comTEST(Serialization, Simple) {
146deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com  ASSERT_TRUE(sfntly::TestSerialization());
147deec0e7851d8f029cf3718bcb61633e8a262c275arthurhsu@google.com}
14853847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com
14953847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.comTEST(Serialization, Bitmap) {
15053847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com  ASSERT_TRUE(sfntly::TestSerializationBitmap());
15153847b66af7e0c1af9928e4da2e978ed3b7c2a25arthurhsu@google.com}
152