1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Resources.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAutoMalloc.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkEndian.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkFontStream.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkOSFile.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypeface.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//#define DUMP_TABLES 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//#define DUMP_TTC_TABLES 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define kFontTableTag_head SkSetFourByteTag('h', 'e', 'a', 'd') 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define kFontTableTag_hhea SkSetFourByteTag('h', 'h', 'e', 'a') 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define kFontTableTag_maxp SkSetFourByteTag('m', 'a', 'x', 'p') 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const struct TagSize { 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFontTableTag fTag; 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t fSize; 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} gKnownTableSizes[] = { 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { kFontTableTag_head, 54 }, 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { kFontTableTag_hhea, 36 }, 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test that getUnitsPerEm() agrees with a direct lookup in the 'head' table 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// (if that table is available). 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_unitsPerEm(skiatest::Reporter* reporter, const sk_sp<SkTypeface>& face) { 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int nativeUPEM = face->getUnitsPerEm(); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int tableUPEM = -1; 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = face->getTableSize(kFontTableTag_head); 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size) { 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // unitsPerEm is at offset 18 into the 'head' table. 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t rawUPEM; 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot face->getTableData(kFontTableTag_head, 18, sizeof(rawUPEM), &rawUPEM); 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tableUPEM = SkEndian_SwapBE16(rawUPEM); 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (tableUPEM >= 0) { 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, tableUPEM == nativeUPEM); 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test that countGlyphs() agrees with a direct lookup in the 'maxp' table 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// (if that table is available). 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_countGlyphs(skiatest::Reporter* reporter, const sk_sp<SkTypeface>& face) { 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int nativeGlyphs = face->countGlyphs(); 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int tableGlyphs = -1; 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = face->getTableSize(kFontTableTag_maxp); 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size) { 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // glyphs is at offset 4 into the 'maxp' table. 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t rawGlyphs; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot face->getTableData(kFontTableTag_maxp, 4, sizeof(rawGlyphs), &rawGlyphs); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tableGlyphs = SkEndian_SwapBE16(rawGlyphs); 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (tableGlyphs >= 0) { 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, tableGlyphs == nativeGlyphs); 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// The following three are all the same code points in various encodings. 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// a中Яיוa 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic uint8_t utf8Chars[] = { 0x61, 0xE4,0xB8,0xAD, 0xD0,0xAF, 0xD7,0x99, 0xD7,0x95, 0xF0,0x9D,0x84,0x9E, 0x61, 0xF0,0xA0,0xAE,0x9F }; 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic uint16_t utf16Chars[] = { 0x0061, 0x4E2D, 0x042F, 0x05D9, 0x05D5, 0xD834,0xDD1E, 0x0061, 0xD842,0xDF9F }; 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic uint32_t utf32Chars[] = { 0x00000061, 0x00004E2D, 0x0000042F, 0x000005D9, 0x000005D5, 0x0001D11E, 0x00000061, 0x00020B9F }; 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct CharsToGlyphs_TestData { 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const void* chars; 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int charCount; 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t charsByteLength; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTypeface::Encoding typefaceEncoding; 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name; 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} static charsToGlyphs_TestData[] = { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { utf8Chars, 8, sizeof(utf8Chars), SkTypeface::kUTF8_Encoding, "Simple UTF-8" }, 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { utf16Chars, 8, sizeof(utf16Chars), SkTypeface::kUTF16_Encoding, "Simple UTF-16" }, 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { utf32Chars, 8, sizeof(utf32Chars), SkTypeface::kUTF32_Encoding, "Simple UTF-32" }, 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test that SkPaint::textToGlyphs agrees with SkTypeface::charsToGlyphs. 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_charsToGlyphs(skiatest::Reporter* reporter, const sk_sp<SkTypeface>& face) { 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t paintGlyphIds[256]; 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t faceGlyphIds[256]; 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t testIndex = 0; testIndex < SK_ARRAY_COUNT(charsToGlyphs_TestData); ++testIndex) { 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CharsToGlyphs_TestData& test = charsToGlyphs_TestData[testIndex]; 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTypeface(face); 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTextEncoding((SkPaint::TextEncoding)test.typefaceEncoding); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.textToGlyphs(test.chars, test.charsByteLength, paintGlyphIds); 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot face->charsToGlyphs(test.chars, test.typefaceEncoding, faceGlyphIds, test.charCount); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < test.charCount; ++i) { 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString name; 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot face->getFamilyName(&name); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString a; 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot a.appendf("%s, paintGlyphIds[%d] = %d, faceGlyphIds[%d] = %d, face = %s", 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test.name, i, (int)paintGlyphIds[i], i, (int)faceGlyphIds[i], name.c_str()); 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, paintGlyphIds[i] == faceGlyphIds[i], a.c_str()); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_fontstream(skiatest::Reporter* reporter, SkStream* stream, int ttcIndex) { 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int n = SkFontStream::GetTableTags(stream, ttcIndex, nullptr); 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoTArray<SkFontTableTag> array(n); 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int n2 = SkFontStream::GetTableTags(stream, ttcIndex, array.get()); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, n == n2); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef DUMP_TTC_TABLES 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString str; 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFontTableTag t = array[i]; 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendUnichar((t >> 24) & 0xFF); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendUnichar((t >> 16) & 0xFF); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendUnichar((t >> 8) & 0xFF); 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str.appendUnichar((t >> 0) & 0xFF); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d:%d] '%s'\n", ttcIndex, i, str.c_str()); 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = SkFontStream::GetTableSize(stream, ttcIndex, array[i]); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t j = 0; j < SK_ARRAY_COUNT(gKnownTableSizes); ++j) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (gKnownTableSizes[j].fTag == array[i]) { 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, gKnownTableSizes[j].fSize == size); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_fontstream(skiatest::Reporter* reporter) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<SkStreamAsset> stream(GetResourceAsStream("fonts/test.ttc")); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!stream) { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Skipping FontHostTest::test_fontstream\n"); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count = SkFontStream::CountTTCEntries(stream.get()); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef DUMP_TTC_TABLES 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("CountTTCEntries %d\n", count); 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < count; ++i) { 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_fontstream(reporter, stream.get(), i); 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_symbolfont(skiatest::Reporter* reporter) { 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkUnichar c = 0xf021; 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t g; 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTypeface(MakeResourceAsTypeface("fonts/SpiderSymbol.ttf")); 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.textToGlyphs(&c, 4, &g); 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!paint.getTypeface()) { 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("Skipping FontHostTest::test_symbolfont\n"); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, g == 3); 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_tables(skiatest::Reporter* reporter, const sk_sp<SkTypeface>& face) { 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (false) { // avoid bit rot, suppress warning 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFontID fontID = face->uniqueID(); 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, fontID); 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count = face->countTables(); 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoTMalloc<SkFontTableTag> storage(count); 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFontTableTag* tags = storage.get(); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count2 = face->getTableTags(tags); 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, count2 == count); 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < count; ++i) { 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = face->getTableSize(tags[i]); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, size > 0); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef DUMP_TABLES 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char name[5]; 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name[0] = (tags[i] >> 24) & 0xFF; 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name[1] = (tags[i] >> 16) & 0xFF; 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name[2] = (tags[i] >> 8) & 0xFF; 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name[3] = (tags[i] >> 0) & 0xFF; 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name[4] = 0; 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%s %d\n", name, size); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t j = 0; j < SK_ARRAY_COUNT(gKnownTableSizes); ++j) { 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (gKnownTableSizes[j].fTag == tags[i]) { 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, gKnownTableSizes[j].fSize == size); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // do we get the same size from GetTableData and GetTableSize 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoMalloc data(size); 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size2 = face->getTableData(tags[i], 0, size, data.get()); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, size2 == size); 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_tables(skiatest::Reporter* reporter) { 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const char* const gNames[] = { 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, // default font 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Helvetica", "Arial", 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Times", "Times New Roman", 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Courier", "Courier New", 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Terminal", "MS Sans Serif", 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Hiragino Mincho ProN", "MS PGothic", 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) { 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkTypeface> face(SkTypeface::MakeFromName(gNames[i], SkFontStyle())); 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (face) { 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef DUMP_TABLES 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("%s\n", gNames[i]); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_tables(reporter, face); 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_unitsPerEm(reporter, face); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_countGlyphs(reporter, face); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_charsToGlyphs(reporter, face); 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Verifies that the advance values returned by generateAdvance and 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * generateMetrics match. 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_advances(skiatest::Reporter* reporter) { 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const char* const faces[] = { 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, // default font 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Arial", "Times", "Times New Roman", "Helvetica", "Courier", 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Courier New", "Verdana", "monospace", 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const struct { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint::Hinting hinting; 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned flags; 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } settings[] = { 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNo_Hinting, 0 }, 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNo_Hinting, SkPaint::kLinearText_Flag }, 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNo_Hinting, SkPaint::kSubpixelText_Flag }, 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kSlight_Hinting, 0 }, 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kSlight_Hinting, SkPaint::kLinearText_Flag }, 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kSlight_Hinting, SkPaint::kSubpixelText_Flag }, 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNormal_Hinting, 0 }, 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNormal_Hinting, SkPaint::kLinearText_Flag }, 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SkPaint::kNormal_Hinting, SkPaint::kSubpixelText_Flag }, 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const struct { 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar fScaleX; 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar fSkewX; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } gScaleRec[] = { 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SK_Scalar1, 0 }, 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SK_Scalar1/2, 0 }, 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // these two exercise obliquing (skew) 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SK_Scalar1, -SK_Scalar1/4 }, 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { SK_Scalar1/2, -SK_Scalar1/4 }, 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot char txt[] = "long.text.with.lots.of.dots."; 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t i = 0; i < SK_ARRAY_COUNT(faces); i++) { 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTypeface(SkTypeface::MakeFromName(faces[i], SkFontStyle())); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t j = 0; j < SK_ARRAY_COUNT(settings); j++) { 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setHinting(settings[j].hinting); 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setLinearText((settings[j].flags & SkPaint::kLinearText_Flag) != 0); 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setSubpixelText((settings[j].flags & SkPaint::kSubpixelText_Flag) != 0); 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (size_t k = 0; k < SK_ARRAY_COUNT(gScaleRec); ++k) { 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTextScaleX(gScaleRec[k].fScaleX); 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTextSkewX(gScaleRec[k].fSkewX); 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bounds; 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // For no hinting and light hinting this should take the 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // optimized generateAdvance path. 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar width1 = paint.measureText(txt, strlen(txt)); 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Requesting the bounds forces a generateMetrics call. 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar width2 = paint.measureText(txt, strlen(txt), &bounds); 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // SkDebugf("Font: %s, generateAdvance: %f, generateMetrics: %f\n", 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // faces[i], SkScalarToFloat(width1), SkScalarToFloat(width2)); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, width1 == width2); 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(FontHost, reporter) { 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_tables(reporter); 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_fontstream(reporter); 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_advances(reporter); 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_symbolfont(reporter); 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// need tests for SkStrSearch 318