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 <vector> 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <algorithm> 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "gtest/gtest.h" 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/type.h" 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/writable_font_data.h" 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/memory_byte_array.h" 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t BYTE_ARRAY_SIZES[] = 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun {1, 7, 127, 128, 129, 255, 256, 257, 666, 1023, 0x10000}; 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// array data for searching 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t LOWER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 4, 7, 13, 127}; 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t UPPER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 5, 12, 16, 256}; 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t kLowerByteArrayForSearchingLength = 5; 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t kUpperByteArrayForSearchingLength = 5; 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// search test result pairs - number to search for; index found at 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t SEARCH_TEST_PAIRS[][2] = { 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun {0, -1}, {1, -1}, {2, 0}, {3, -1}, {4, 1}, {5, 1}, {6, -1}, {12, 2}, 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun {13, 3}, {17, -1}, {126, -1}, {127, 4}, {256, 4}, {257, -1}, {0x1000, -1} 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t kSearchTestPairsLength = 15; 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// offset and start index data for searching data 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// array data size, lower_start_index, lower_offset, upper_start_index, 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// upper_offset 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t SEARCH_TEST_OFFSETS[][5] = { 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // lower[], upper[] 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength) 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * DataSize::kUSHORT, 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 0, 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kLowerByteArrayForSearchingLength * DataSize::kUSHORT, 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT }, 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // {lower, upper} [] 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength) 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * DataSize::kUSHORT, 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 0, 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2 * DataSize::kUSHORT, 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2 * DataSize::kUSHORT }, 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // upper[], lower[] 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength) 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * DataSize::kUSHORT, 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kLowerByteArrayForSearchingLength * DataSize::kUSHORT, 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 0, 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT }, 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // {upper, lower} [] 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength) 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * DataSize::kUSHORT, 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DataSize::kUSHORT, 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2 * DataSize::kUSHORT, 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 0, 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2 * DataSize::kUSHORT } 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int32_t kSearchTestOffsetLength = 4; 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunReadableFontData* 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFillTestFontDataWithShortsForSearching(WritableFontData* wfd, 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const int32_t* lower_data, 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t lower_start_index, 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t lower_offset, 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const int32_t* upper_data, 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t upper_start_index, 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t upper_offset) { 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // lower data 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int offset = lower_start_index; 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < kLowerByteArrayForSearchingLength; ++i) { 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd->WriteUShort(offset, lower_data[i]); 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun offset += lower_offset; 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // upper data 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun offset = upper_start_index; 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < kUpperByteArrayForSearchingLength; ++i) { 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd->WriteUShort(offset, upper_data[i]); 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun offset += upper_offset; 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return wfd; 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestReadableFontDataSearching() { 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < kSearchTestOffsetLength; ++i) { 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const int32_t* array_setup_offset = SEARCH_TEST_OFFSETS[i]; 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr wfd; 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd.Attach(WritableFontData::CreateWritableFontData(array_setup_offset[0])); 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FillTestFontDataWithShortsForSearching(wfd, 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun LOWER_BYTE_ARRAY_FOR_SEARCHING, 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[1], 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[2], 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UPPER_BYTE_ARRAY_FOR_SEARCHING, 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[3], 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[4]); 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t j = 0; j < kSearchTestPairsLength; ++j) { 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun const int32_t* test_case = SEARCH_TEST_PAIRS[j]; 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t found = wfd->SearchUShort(array_setup_offset[1], 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[2], 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[3], 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun array_setup_offset[4], 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun kLowerByteArrayForSearchingLength, 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun test_case[0]); 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_FONTDATA) 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "Searching for %d; Got %d; Expected %d; " 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun "[test %d][offset %d]\n", 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun test_case[0], found, test_case[1], j, i); 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_EQ(test_case[1], found); 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid FillTestByteArray(ByteArray* ba, int32_t size) { 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t i = 0; i < size; ++i) { 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ba->Put(i, (byte_t)(i % 256)); 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid ReadFontDataWithSingleByte(ReadableFontData* rfd, ByteVector* buffer) { 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun buffer->resize(rfd->Length()); 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t index = 0; index < rfd->Length(); ++index) { 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun (*buffer)[index] = (byte_t)(rfd->ReadByte(index)); 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid ReadFontDataWithBuffer(ReadableFontData* rfd, 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t buffer_size, 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector* b) { 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector buffer(buffer_size); 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b->resize(rfd->Length()); 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 0; 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (index < rfd->Length()) { 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t bytes_read = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size()); 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_GE(bytes_read, 0); 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::copy(buffer.begin(), buffer.begin() + bytes_read, b->begin() + index); 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += bytes_read; 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid ReadFontDataWithSlidingWindow(ReadableFontData* rfd, int32_t window_size, 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector* b) { 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b->resize(rfd->Length()); 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 0; 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (index < rfd->Length()) { 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t actual_window_size = 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun std::min<int32_t>(window_size, b->size() - index); 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t bytes_read = 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun rfd->ReadBytes(index, &((*b)[0]), index, actual_window_size); 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_GE(bytes_read, 0); 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += bytes_read; 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid WriteFontDataWithSingleByte(ReadableFontData* rfd, WritableFontData* wfd) { 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t index = 0; index < rfd->Length(); ++index) { 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun byte_t b = (byte_t)(rfd->ReadByte(index)); 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd->WriteByte(index, b); 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid WriteFontDataWithBuffer(ReadableFontData* rfd, 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* wfd, 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t buffer_size) { 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector buffer(buffer_size); 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 0; 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (index < rfd->Length()) { 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t bytesRead = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size()); 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd->WriteBytes(index, &(buffer[0]), 0, buffer.size()); 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += bytesRead; 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid WriteFontDataWithSlidingWindow(ReadableFontData* rfd, 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontData* wfd, 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t window_size) { 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector b(rfd->Length()); 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t index = 0; 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (index < rfd->Length()) { 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t sliding_size = std::min<int32_t>(window_size, b.size() - index); 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t bytes_read = rfd->ReadBytes(index, &(b[0]), index, sliding_size); 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun wfd->WriteBytes(index, &(b[0]), index, sliding_size); 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun index += bytes_read; 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool ReadComparison(int32_t offset, 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length, 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* rfd1, 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontData* rfd2) { 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_TRUE(length == rfd2->Length()); 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteVector b1, b2; 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b1.resize(length); 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b2.resize(length); 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // single byte reads 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithSingleByte(rfd1, &b1); 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithSingleByte(rfd2, &b2); 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_EQ(memcmp(&(b1[offset]), &(b2[0]), length), 0); 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // buffer reads 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t increments = std::max<int32_t>(length / 11, 1); 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t buffer_size = 1; buffer_size <= length; 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun buffer_size += increments) { 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b1.clear(); 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b2.clear(); 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b1.resize(length); 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b2.resize(length); 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithBuffer(rfd1, buffer_size, &b1); 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithBuffer(rfd2, buffer_size, &b2); 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int result = memcmp(&(b1[offset]), &(b2[0]), length); 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_EQ(result, 0); 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // sliding window reads 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t window_size = 1; window_size <= length; 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun window_size += increments) { 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b1.clear(); 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b2.clear(); 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b1.resize(length); 24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun b2.resize(length); 24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithSlidingWindow(rfd1, window_size, &b1); 24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadFontDataWithSlidingWindow(rfd2, window_size, &b2); 24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int result = memcmp(&(b1[offset]), &(b2[0]), length); 24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_EQ(result, 0); 25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid SlicingReadTest(ReadableFontData* rfd) { 25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "read - trim = "); 25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1; 25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun trim += (rfd->Length() / 21) + 1) { 25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "%d ", trim); 25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length = rfd->Length() - 2 * trim; 26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr slice; 26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length))); 26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_TRUE(ReadComparison(trim, length, rfd, slice)); 26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "\n"); 26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid SlicingWriteTest(ReadableFontData* rfd, WritableFontData* wfd) { 26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "write - trim = "); 26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1; 27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun trim += (rfd->Length() / 21) + 1) { 27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "%d ", trim); 27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t length = rfd->Length() - 2 * trim; 27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr w_slice; 27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr r_slice; 27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // single byte writes 27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length))); 27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length))); 27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WriteFontDataWithSingleByte(r_slice, w_slice); 28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice)); 28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // buffer writes 28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t increments = std::max<int32_t>(length / 11, 1); 28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int32_t buffer_size = 1; buffer_size < length; 28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun buffer_size += increments) { 28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length))); 28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length))); 28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WriteFontDataWithBuffer(r_slice, w_slice, buffer_size); 28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice)); 29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // sliding window writes 29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (int window_size = 1; window_size < length; window_size += increments) { 29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length))); 29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length))); 29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WriteFontDataWithSlidingWindow(r_slice, w_slice, window_size); 29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice)); 29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun fprintf(stderr, "\n"); 30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestReadableFontData() { 30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) { 30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = BYTE_ARRAY_SIZES[i]; 30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteArrayPtr ba = new MemoryByteArray(size); 30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FillTestByteArray(ba, size); 30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ReadableFontDataPtr rfd = new ReadableFontData(ba); 30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SlicingReadTest(rfd); 31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TestWritableFontData() { 31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) { 31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int32_t size = BYTE_ARRAY_SIZES[i]; 31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteArrayPtr ba = new MemoryByteArray(size); 31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FillTestByteArray(ba, size); 31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr wfd = new WritableFontData(ba); 32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SlicingReadTest(wfd); 32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ByteArrayPtr temp = new MemoryByteArray(size); 32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun WritableFontDataPtr wfd_copy = new WritableFontData(temp); 32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun SlicingWriteTest(wfd, wfd_copy); 32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(FontData, ReadableFontDataSearching) { 33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ASSERT_TRUE(sfntly::TestReadableFontDataSearching()); 33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTEST(FontData, All) { 33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ASSERT_TRUE(sfntly::TestReadableFontData()); 33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ASSERT_TRUE(sfntly::TestWritableFontData()); 33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 338