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
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/font_input_stream.h"
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/memory_byte_array.h"
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font.h"
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font_factory.h"
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/font_header_table.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/table.h"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/generic_table_builder.h"
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/table_based_table_builder.h"
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/tag.h"
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/file_input_stream.h"
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_data.h"
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_font_utils.h"
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestFontParsing() {
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ByteVector input_buffer;
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFile(SAMPLE_TTF_FILE, &input_buffer);
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory;
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory.Attach(FontFactory::GetInstance());
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // File based
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array;
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder = font_builder_array[0];
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Memory based
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array2;
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->LoadFontsForBuilding(&input_buffer, &font_builder_array2);
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder2 = font_builder_array2[0];
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_TRUE(font_builder->HasTableBuilder(TTF_KNOWN_TAGS[i]));
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_TRUE(font_builder2->HasTableBuilder(TTF_KNOWN_TAGS[i]));
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Generic table
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<GenericTableBuilder> gdef_builder =
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<GenericTableBuilder*>(font_builder->GetTableBuilder(Tag::feat));
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  HeaderPtr gdef_header = gdef_builder->header();
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(gdef_header->length(), TTF_LENGTH[SAMPLE_TTF_FEAT]);
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(gdef_header->offset(), TTF_OFFSET[SAMPLE_TTF_FEAT]);
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(gdef_header->checksum(), TTF_CHECKSUM[SAMPLE_TTF_FEAT]);
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_TRUE(gdef_header->checksum_valid());
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  WritableFontDataPtr wfd;
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  wfd.Attach(gdef_builder->Data());
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ByteVector b;
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  b.resize(TTF_LENGTH[SAMPLE_TTF_FEAT]);
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  wfd->ReadBytes(0, &(b[0]), 0, TTF_LENGTH[SAMPLE_TTF_FEAT]);
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(memcmp(&(b[0]), TTF_FEAT_DATA, TTF_LENGTH[SAMPLE_TTF_FEAT]), 0);
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Header table
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontHeaderTableBuilderPtr header_builder =
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      down_cast<FontHeaderTable::Builder*>(
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          font_builder->GetTableBuilder(Tag::head));
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  HeaderPtr header_header = header_builder->header();
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(header_header->length(), TTF_LENGTH[SAMPLE_TTF_HEAD]);
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(header_header->offset(), TTF_OFFSET[SAMPLE_TTF_HEAD]);
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(header_header->checksum(), TTF_CHECKSUM[SAMPLE_TTF_HEAD]);
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_TRUE(header_header->checksum_valid());
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Data conformance
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (size_t i = 0; i < SAMPLE_TTF_KNOWN_TAGS; ++i) {
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    ByteVector b1, b2;
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    b1.resize(TTF_LENGTH[i]);
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    b2.resize(TTF_LENGTH[i]);
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    TableBuilderPtr builder1 =
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        font_builder->GetTableBuilder(TTF_KNOWN_TAGS[i]);
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    TableBuilderPtr builder2 =
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        font_builder2->GetTableBuilder(TTF_KNOWN_TAGS[i]);
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    WritableFontDataPtr wfd1;
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    wfd1.Attach(builder1->Data());
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    WritableFontDataPtr wfd2;
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    wfd2.Attach(builder2->Data());
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    wfd1->ReadBytes(0, &(b1[0]), 0, TTF_LENGTH[i]);
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    wfd2->ReadBytes(0, &(b2[0]), 0, TTF_LENGTH[i]);
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), TTF_LENGTH[i]), 0);
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestTTFReadWrite() {
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory;
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory.Attach(FontFactory::GetInstance());
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array;
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder = font_builder_array[0];
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr font;
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  font.Attach(font_builder->Build());
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryOutputStream output_stream;
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->SerializeFont(font, &output_stream);
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_GE(output_stream.Size(), SAMPLE_TTF_SIZE);
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestTTFMemoryBasedReadWrite() {
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ByteVector input_buffer;
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFile(SAMPLE_TTF_FILE, &input_buffer);
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontFactoryPtr factory;
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory.Attach(FontFactory::GetInstance());
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderArray font_builder_array;
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->LoadFontsForBuilding(&input_buffer, &font_builder_array);
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontBuilderPtr font_builder = font_builder_array[0];
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontPtr font;
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  font.Attach(font_builder->Build());
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  MemoryOutputStream output_stream;
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  factory->SerializeFont(font, &output_stream);
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_GE(output_stream.Size(), input_buffer.size());
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(FontParsing, All) {
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestFontParsing());
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestTTFReadWrite());
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_TRUE(sfntly::TestTTFMemoryBasedReadWrite());
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
141