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// Must include this before ICU to avoid stdint redefinition issue.
18#include "sfntly/port/type.h"
19
20#include <unicode/ustring.h>
21#include <unicode/unistr.h>
22
23#include "gtest/gtest.h"
24#include "sfntly/data/memory_byte_array.h"
25#include "sfntly/font.h"
26#include "sfntly/font_factory.h"
27#include "sfntly/port/memory_input_stream.h"
28#include "sfntly/port/memory_output_stream.h"
29#include "sfntly/table/core/name_table.h"
30#include "sfntly/tag.h"
31#include "test/test_data.h"
32#include "test/test_font_utils.h"
33
34namespace sfntly {
35
36static ByteVector input_buffer;
37
38void LoadTestFile(FontFactory* factory, FontBuilderArray* font_builders) {
39  assert(factory);
40  assert(font_builders);
41  if (input_buffer.empty()) {
42    LoadFile(SAMPLE_TTF_FILE, &input_buffer);
43  }
44  factory->LoadFontsForBuilding(&input_buffer, font_builders);
45}
46
47bool TestChangeOneName() {
48  FontFactoryPtr factory;
49  factory.Attach(FontFactory::GetInstance());
50  FontBuilderArray font_builder_array;
51  LoadTestFile(factory, &font_builder_array);
52  FontBuilderPtr font_builder = font_builder_array[0];
53
54  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
55      font_builder->GetTableBuilder(Tag::name));
56
57  // Change the font name.
58  NameEntryBuilderPtr neb =
59      name_builder->NameBuilder(PlatformId::kWindows,
60                                WindowsEncodingId::kUnicodeUCS2,
61                                WindowsLanguageId::kEnglish_UnitedStates,
62                                NameId::kFontFamilyName);
63  U_STRING_DECL(new_name, "Timothy", 7);
64  neb->SetName(new_name);
65
66  // Build the font.
67  FontPtr font;
68  font.Attach(font_builder->Build());
69
70  // Serialize and reload the serialized font.
71  MemoryOutputStream os;
72  factory->SerializeFont(font, &os);
73  MemoryInputStream is;
74  is.Attach(os.Get(), os.Size());
75  FontArray font_array;
76  factory->LoadFonts(&is, &font_array);
77  FontPtr new_font = font_array[0];
78
79  // Check the font name.
80  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
81  UChar* name = name_table->Name(PlatformId::kWindows,
82                                 WindowsEncodingId::kUnicodeUCS2,
83                                 WindowsLanguageId::kEnglish_UnitedStates,
84                                 NameId::kFontFamilyName);
85  EXPECT_TRUE(name != NULL);
86  EXPECT_EQ(u_strcmp(name, new_name), 0);
87  delete[] name;
88  return true;
89}
90
91bool TestModifyNameTableAndRevert() {
92  FontFactoryPtr factory;
93  factory.Attach(FontFactory::GetInstance());
94  FontBuilderArray font_builder_array;
95  LoadTestFile(factory, &font_builder_array);
96  FontBuilderPtr font_builder = font_builder_array[0];
97
98  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
99      font_builder->GetTableBuilder(Tag::name));
100
101  // Change the font name.
102  NameEntryBuilderPtr neb =
103      name_builder->NameBuilder(PlatformId::kWindows,
104                                WindowsEncodingId::kUnicodeUCS2,
105                                WindowsLanguageId::kEnglish_UnitedStates,
106                                NameId::kFontFamilyName);
107  NameTable::NameEntry* neb_entry = neb->name_entry();
108  UChar* original_name = neb_entry->Name();
109  EXPECT_TRUE(original_name != NULL);
110
111  U_STRING_DECL(new_name, "Timothy", 7);
112  neb->SetName(new_name);
113  name_builder->RevertNames();
114
115  // Build the font.
116  FontPtr font;
117  font.Attach(font_builder->Build());
118
119  // Serialize and reload the serialized font.
120  MemoryOutputStream os;
121  factory->SerializeFont(font, &os);
122  MemoryInputStream is;
123  is.Attach(os.Get(), os.Size());
124  FontArray font_array;
125  factory->LoadFonts(&is, &font_array);
126  FontPtr new_font = font_array[0];
127
128  // Check the font name.
129  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
130  UChar* name = name_table->Name(PlatformId::kWindows,
131                                 WindowsEncodingId::kUnicodeUCS2,
132                                 WindowsLanguageId::kEnglish_UnitedStates,
133                                 NameId::kFontFamilyName);
134
135  EXPECT_EQ(u_strcmp(name, original_name), 0);
136  delete[] name;
137  delete[] original_name;
138
139  return true;
140}
141
142bool TestRemoveOneName() {
143  FontFactoryPtr factory;
144  factory.Attach(FontFactory::GetInstance());
145  FontBuilderArray font_builder_array;
146  LoadTestFile(factory, &font_builder_array);
147  FontBuilderPtr font_builder = font_builder_array[0];
148
149  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
150      font_builder->GetTableBuilder(Tag::name));
151
152  EXPECT_TRUE(name_builder->Has(PlatformId::kWindows,
153                                WindowsEncodingId::kUnicodeUCS2,
154                                WindowsLanguageId::kEnglish_UnitedStates,
155                                NameId::kFontFamilyName));
156  EXPECT_TRUE(name_builder->Remove(PlatformId::kWindows,
157                                   WindowsEncodingId::kUnicodeUCS2,
158                                   WindowsLanguageId::kEnglish_UnitedStates,
159                                   NameId::kFontFamilyName));
160
161  // Build the font.
162  FontPtr font;
163  font.Attach(font_builder->Build());
164
165  // Serialize and reload the serialized font.
166  MemoryOutputStream os;
167  factory->SerializeFont(font, &os);
168  MemoryInputStream is;
169  is.Attach(os.Get(), os.Size());
170  FontArray font_array;
171  factory->LoadFonts(&is, &font_array);
172  FontPtr new_font = font_array[0];
173
174  // Check the font name.
175  NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
176  UChar* name = name_table->Name(PlatformId::kWindows,
177                                 WindowsEncodingId::kUnicodeUCS2,
178                                 WindowsLanguageId::kEnglish_UnitedStates,
179                                 NameId::kFontFamilyName);
180  EXPECT_TRUE(name == NULL);
181
182  return true;
183}
184
185// Note: Function is not implemented but the test case is built.  Uncomment
186//       when NameTable::clear() is implemented.
187/*
188bool TestClearAllNamesAndSetOne() {
189  FontFactoryPtr factory;
190  factory.Attach(FontFactory::GetInstance());
191  FontBuilderArray font_builder_array;
192  LoadTestFile(factory, &font_builder_array);
193  FontBuilderPtr font_builder = font_builder_array[0];
194
195  NameTableBuilderPtr name_builder = down_cast<NameTable::Builder*>(
196      font_builder->GetTableBuilder(Tag::name));
197
198  EXPECT_GT(name_builder->builderCount(), 0);
199  name_builder->clear();
200  EXPECT_EQ(name_builder->builderCount(), 0);
201
202  // Change the font name.
203  NameEntryBuilderPtr neb =
204      name_builder->NameBuilder(PlatformId::kWindows,
205                                WindowsEncodingId::kUnicodeUCS2,
206                                WindowsLanguageId::kEnglish_UnitedStates,
207                                NameId::kFontFamilyName);
208  U_STRING_DECL(new_name, "Fred", 4);
209  neb->SetName(new_name);
210
211  // Build the font.
212  FontPtr font = font_builder->Build();
213
214  // Serialize and reload the serialized font.
215  MemoryOutputStream os;
216  factory->SerializeFont(font, &os);
217  FontArray font_array;
218  ByteArrayPtr new_ba = new MemoryByteArray(os.Get(), os.Size());
219  factory->LoadFonts(new_ba, &font_array);
220  FontPtr new_font = font_array[0];
221
222  // Check the font name.
223  NameTablePtr name_table = down_cast<NameTable*>(font->table(Tag::name));
224  UChar* name = name_table->Name(PlatformId::kWindows,
225                                 WindowsEncodingId::kUnicodeUCS2,
226                                 WindowsLanguageId::kEnglish_UnitedStates,
227                                 NameId::kFontFamilyName);
228  EXPECT_EQ(name_table->NameCount(), 1);
229  EXPECT_EQ(u_strcmp(name, new_name), 0);
230
231  delete[] name;
232  return true;
233}
234*/
235
236}  // namespace sfntly
237
238TEST(NameEditing, All) {
239  EXPECT_TRUE(sfntly::TestChangeOneName());
240  EXPECT_TRUE(sfntly::TestModifyNameTableAndRevert());
241  EXPECT_TRUE(sfntly::TestRemoveOneName());
242}
243