1a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com/*
2a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com *
4a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * you may not use this file except in compliance with the License.
6a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * You may obtain a copy of the License at
7a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com *
8a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com *
10a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * Unless required by applicable law or agreed to in writing, software
11a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * See the License for the specific language governing permissions and
14a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com * limitations under the License.
15a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com */
16a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
17a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include <string.h>
18a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
19a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include <vector>
20a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include <string>
21a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include <algorithm>
22a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
23a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/font.h"
24a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/font_factory.h"
25a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/table/core/cmap_table.h"
26a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/tag.h"
27a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/port/type.h"
28a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "sfntly/port/refcount.h"
29a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "test/test_data.h"
30a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "test/test_font_utils.h"
31a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
32a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#include "gtest/gtest.h"
33a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
34a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if GTEST_HAS_PARAM_TEST
35a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
36a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comnamespace sfntly {
37a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comusing ::testing::TestWithParam;
38a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comusing ::testing::Values;
39a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
40a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comtypedef std::vector<bool> BitSet;
41a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
42a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comclass CMapIteratorTestCase {
43a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com public:
44a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  CMapIteratorTestCase(int32_t platform_id, int32_t encoding_id,
45a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                       const char* file_name)
46a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      : platform_id_(platform_id),
47a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com        encoding_id_(encoding_id),
48a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com        file_name_(file_name) {
49a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  }
50a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  ~CMapIteratorTestCase() {}
51a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t platform_id() const { return platform_id_; }
52a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t encoding_id() const { return encoding_id_; }
53a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  const char* file_name() const { return file_name_; }
54a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
55a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com private:
56a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t platform_id_;
57a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t encoding_id_;
58a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  const char* file_name_;
59a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com};
60a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
61a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comclass CMapIteratorTests
62a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    : public ::testing::TestWithParam<CMapIteratorTestCase> {
63a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com public:
64a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  virtual void SetUp();
65a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  virtual void TearDown() {}
66a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
67a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  BitSet* GenerateCMapEntries(int32_t start, int32_t count);
68a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t CompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator*
69a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                                   character_iterator,
70a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                                   BitSet* bit_set);
71a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
72a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  Ptr<CMapTable::CMap> cmap_;
73a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com};
74a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
75a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comvoid CMapIteratorTests::SetUp() {
76a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  FontArray fonts;
77a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  Ptr<FontFactory> font_factory;
78a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  const char* file_name = GetParam().file_name();
79a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  LoadFont(file_name, font_factory, &fonts);
80a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  Ptr<Font> font;
81a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  font.Attach(fonts[0].Detach());
82a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
83a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  ASSERT_FALSE(cmap_table == NULL);
84a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  cmap_.Attach(cmap_table->GetCMap(GetParam().platform_id(),
85a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                                   GetParam().encoding_id()));
86a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  ASSERT_FALSE(cmap_ == NULL);
87a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com}
88a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
89a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comBitSet* CMapIteratorTests::GenerateCMapEntries(int32_t start, int32_t count) {
90a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  BitSet* entries = new BitSet(count);
91a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  for (int32_t c = start; c < start + count; ++c) {
92a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    int32_t g = cmap_->GlyphId(c);
93a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    if (g != CMapTable::NOTDEF)
94a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      (*entries)[c] = true;
95a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  }
96a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  return entries;
97a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com}
98a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
99a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comint32_t
100a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapIteratorTests::
101a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator* character_iterator,
102a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                         BitSet* bit_set) {
103a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  int32_t iterator_not_bitset_count = 0;
104a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  BitSet::iterator end = bit_set->end(),
105a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      beginning = bit_set->begin(),
106a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      init_beginning = beginning,
107a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      current = std::find(beginning, end, true);
108a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  for (int32_t next_bit = current - beginning;
109a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com       character_iterator->HasNext() && current != end;
110a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com       next_bit = current - init_beginning) {
111a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    int32_t c = character_iterator->Next();
112a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    EXPECT_TRUE(c <= next_bit || current == end);
113a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    if (!(c <= next_bit || current == end))
114a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      return -1;
115a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    if (c == next_bit) {
116a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      beginning = current + 1;
117a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      current = std::find(beginning, end, true);
118a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    } else {
119a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com      iterator_not_bitset_count++;
120a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com    }
121a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  }
122a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  EXPECT_EQ(end, current);
123a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#if defined (SFNTLY_DEBUG_CMAP)
124a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  fprintf(stderr, "%s %d: Differences between iterator and bitset: %d\n",
125a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com          cmap_->format(), GetParam().file_name(), iterator_not_bitset_count);
126a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif
127a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  return iterator_not_bitset_count;
128a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com}
129a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
130a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comTEST_P(CMapIteratorTests, IteratorTest) {
131a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  BitSet* bit_set = GenerateCMapEntries(0, 0x10ffff);
132a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  CMapTable::CMap::CharacterIterator* character_iterator = NULL;
133a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  character_iterator = cmap_->Iterator();
134a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  EXPECT_NE(character_iterator,
135a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com            reinterpret_cast<CMapTable::CMap::CharacterIterator*>(NULL));
136a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  CompareCMapIterAndBitSet(character_iterator, bit_set);
137a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  delete character_iterator;
138a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  delete bit_set;
139a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com}
140a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
141a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comCMapIteratorTestCase kCMapIteratorTestsTestCases[] = {
142a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com  CMapIteratorTestCase(CMapTable::WINDOWS_BMP.platform_id,
143a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                       CMapTable::WINDOWS_BMP.encoding_id,
144a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                       SAMPLE_TTF_FILE)
145a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com};
146a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
147a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comINSTANTIATE_TEST_CASE_P(CMapIteratorTests,
148a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                        CMapIteratorTests,
149a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com                        ::testing::ValuesIn(kCMapIteratorTestsTestCases));
150a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com}
151a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
152a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#else
153a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
154a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.comTEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
155a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com
156a8be98eb7c7b56644732b866346cf8b852592170dfilimon@google.com#endif  // GTEST_HAS_PARAM
157