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 <string.h>
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <vector>
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <string>
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <algorithm>
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/font_factory.h"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/core/cmap_table.h"
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/tag.h"
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/type.h"
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/refcount.h"
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_data.h"
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/test_font_utils.h"
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "gtest/gtest.h"
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if GTEST_HAS_PARAM_TEST
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunusing ::testing::TestWithParam;
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunusing ::testing::Values;
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<bool> BitSet;
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass CMapIteratorTestCase {
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public:
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CMapIteratorTestCase(int32_t platform_id, int32_t encoding_id,
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                       const char* file_name)
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      : platform_id_(platform_id),
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        encoding_id_(encoding_id),
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        file_name_(file_name) {
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ~CMapIteratorTestCase() {}
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t platform_id() const { return platform_id_; }
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t encoding_id() const { return encoding_id_; }
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const char* file_name() const { return file_name_; }
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private:
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t platform_id_;
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t encoding_id_;
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const char* file_name_;
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass CMapIteratorTests
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : public ::testing::TestWithParam<CMapIteratorTestCase> {
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public:
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual void SetUp();
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual void TearDown() {}
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitSet* GenerateCMapEntries(int32_t start, int32_t count);
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t CompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator*
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                   character_iterator,
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                   BitSet* bit_set);
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<CMapTable::CMap> cmap_;
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid CMapIteratorTests::SetUp() {
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  FontArray fonts;
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<FontFactory> font_factory;
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  const char* file_name = GetParam().file_name();
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  LoadFont(file_name, font_factory, &fonts);
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<Font> font;
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  font.Attach(fonts[0].Detach());
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_FALSE(cmap_table == NULL);
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  cmap_.Attach(cmap_table->GetCMap(GetParam().platform_id(),
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                   GetParam().encoding_id()));
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  ASSERT_FALSE(cmap_ == NULL);
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunBitSet* CMapIteratorTests::GenerateCMapEntries(int32_t start, int32_t count) {
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitSet* entries = new BitSet(count);
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (int32_t c = start; c < start + count; ++c) {
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t g = cmap_->GlyphId(c);
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    if (g != CMapTable::NOTDEF)
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      (*entries)[c] = true;
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return entries;
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapIteratorTests::
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCompareCMapIterAndBitSet(CMapTable::CMap::CharacterIterator* character_iterator,
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                         BitSet* bit_set) {
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t iterator_not_bitset_count = 0;
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitSet::iterator end = bit_set->end(),
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      beginning = bit_set->begin(),
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      init_beginning = beginning,
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      current = std::find(beginning, end, true);
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (int32_t next_bit = current - beginning;
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       character_iterator->HasNext() && current != end;
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       next_bit = current - init_beginning) {
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t c = character_iterator->Next();
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EXPECT_TRUE(c <= next_bit || current == end);
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    if (!(c <= next_bit || current == end))
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return -1;
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    if (c == next_bit) {
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      beginning = current + 1;
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      current = std::find(beginning, end, true);
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    } else {
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      iterator_not_bitset_count++;
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_EQ(end, current);
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_CMAP)
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  fprintf(stderr, "%s %d: Differences between iterator and bitset: %d\n",
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          cmap_->format(), GetParam().file_name(), iterator_not_bitset_count);
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return iterator_not_bitset_count;
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST_P(CMapIteratorTests, IteratorTest) {
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitSet* bit_set = GenerateCMapEntries(0, 0x10ffff);
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CMapTable::CMap::CharacterIterator* character_iterator = NULL;
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  character_iterator = cmap_->Iterator();
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  EXPECT_NE(character_iterator,
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            reinterpret_cast<CMapTable::CMap::CharacterIterator*>(NULL));
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CompareCMapIterAndBitSet(character_iterator, bit_set);
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  delete character_iterator;
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  delete bit_set;
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCMapIteratorTestCase kCMapIteratorTestsTestCases[] = {
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CMapIteratorTestCase(CMapTable::WINDOWS_BMP.platform_id,
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                       CMapTable::WINDOWS_BMP.encoding_id,
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                       SAMPLE_TTF_FILE)
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunINSTANTIATE_TEST_CASE_P(CMapIteratorTests,
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                        CMapIteratorTests,
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                        ::testing::ValuesIn(kCMapIteratorTestsTestCases));
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif  // GTEST_HAS_PARAM
157