OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "SkPaint.h" | 9 #include "SkPaint.h" |
10 #include "SkFontStream.h" | 10 #include "SkFontStream.h" |
| 11 #include "SkOSFile.h" |
11 #include "SkStream.h" | 12 #include "SkStream.h" |
12 #include "SkTypeface.h" | 13 #include "SkTypeface.h" |
13 #include "SkEndian.h" | 14 #include "SkEndian.h" |
14 | 15 |
15 //#define DUMP_TABLES | 16 //#define DUMP_TABLES |
16 //#define DUMP_TTC_TABLES | 17 //#define DUMP_TTC_TABLES |
17 | 18 |
18 #define kFontTableTag_head SkSetFourByteTag('h', 'e', 'a', 'd') | 19 #define kFontTableTag_head SkSetFourByteTag('h', 'e', 'a', 'd') |
19 #define kFontTableTag_hhea SkSetFourByteTag('h', 'h', 'e', 'a') | 20 #define kFontTableTag_hhea SkSetFourByteTag('h', 'h', 'e', 'a') |
20 #define kFontTableTag_maxp SkSetFourByteTag('m', 'a', 'x', 'p') | 21 #define kFontTableTag_maxp SkSetFourByteTag('m', 'a', 'x', 'p') |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 } | 66 } |
66 | 67 |
67 if (tableGlyphs >= 0) { | 68 if (tableGlyphs >= 0) { |
68 REPORTER_ASSERT(reporter, tableGlyphs == nativeGlyphs); | 69 REPORTER_ASSERT(reporter, tableGlyphs == nativeGlyphs); |
69 } else { | 70 } else { |
70 // not sure this is a bug, but lets report it for now as info. | 71 // not sure this is a bug, but lets report it for now as info. |
71 SkDebugf("--- typeface returned 0 glyphs [%X]\n", face->uniqueID()); | 72 SkDebugf("--- typeface returned 0 glyphs [%X]\n", face->uniqueID()); |
72 } | 73 } |
73 } | 74 } |
74 | 75 |
| 76 // The following three are all the same code points in various encodings. |
| 77 static uint8_t utf8Chars[] = { 0x61, 0xE4, 0xB8, 0xAD, 0xD0, 0xAF, 0xD7, 0x99, 0
xD7, 0x95, 0xF0, 0x9D, 0x84, 0x9E, 0x61 }; |
| 78 static uint16_t utf16Chars[] = { 0x0061, 0x4E2D, 0x042F, 0x05D9, 0x05D5, 0xD834,
0xDD1E, 0x0061 }; |
| 79 static uint32_t utf32Chars[] = { 0x00000061, 0x00004E2D, 0x0000042F, 0x000005D9,
0x000005D5, 0x0001D11E, 0x00000061 }; |
| 80 |
| 81 struct CharsToGlyphs_TestData { |
| 82 const void* chars; |
| 83 int charCount; |
| 84 size_t charsByteLength; |
| 85 SkTypeface::Encoding typefaceEncoding; |
| 86 const char* name; |
| 87 } static charsToGlyphs_TestData[] = { |
| 88 { utf8Chars, 7, sizeof(utf8Chars), SkTypeface::kUTF8_Encoding, "Simple UTF-8
" }, |
| 89 { utf16Chars, 7, sizeof(utf16Chars), SkTypeface::kUTF16_Encoding, "Simple UT
F-16" }, |
| 90 { utf32Chars, 7, sizeof(utf32Chars), SkTypeface::kUTF32_Encoding, "Simple UT
F-32" }, |
| 91 }; |
| 92 |
| 93 // Test that SkPaint::textToGlyphs agrees with SkTypeface::charsToGlyphs. |
| 94 static void test_charsToGlyphs(skiatest::Reporter* reporter, SkTypeface* face) { |
| 95 uint16_t paintGlyphIds[256]; |
| 96 uint16_t faceGlyphIds[256]; |
| 97 |
| 98 for (size_t testIndex = 0; testIndex < SK_ARRAY_COUNT(charsToGlyphs_TestData
); ++testIndex) { |
| 99 CharsToGlyphs_TestData& test = charsToGlyphs_TestData[testIndex]; |
| 100 |
| 101 SkPaint paint; |
| 102 paint.setTypeface(face); |
| 103 paint.setTextEncoding((SkPaint::TextEncoding)test.typefaceEncoding); |
| 104 paint.textToGlyphs(test.chars, test.charsByteLength, paintGlyphIds); |
| 105 |
| 106 face->charsToGlyphs(test.chars, test.typefaceEncoding, faceGlyphIds, tes
t.charCount); |
| 107 |
| 108 for (int i = 0; i < test.charCount; ++i) { |
| 109 SkString name; |
| 110 face->getFamilyName(&name); |
| 111 SkString a; |
| 112 a.appendf("%s, paintGlyphIds[%d] = %d, faceGlyphIds[%d] = %d, face =
%s", |
| 113 test.name, i, (int)paintGlyphIds[i], i, (int)faceGlyphIds[
i], name.c_str()); |
| 114 REPORTER_ASSERT_MESSAGE(reporter, paintGlyphIds[i] == faceGlyphIds[i
], a.c_str()); |
| 115 } |
| 116 } |
| 117 } |
| 118 |
75 static void test_fontstream(skiatest::Reporter* reporter, | 119 static void test_fontstream(skiatest::Reporter* reporter, |
76 SkStream* stream, int ttcIndex) { | 120 SkStream* stream, int ttcIndex) { |
77 int n = SkFontStream::GetTableTags(stream, ttcIndex, NULL); | 121 int n = SkFontStream::GetTableTags(stream, ttcIndex, NULL); |
78 SkAutoTArray<SkFontTableTag> array(n); | 122 SkAutoTArray<SkFontTableTag> array(n); |
79 | 123 |
80 int n2 = SkFontStream::GetTableTags(stream, ttcIndex, array.get()); | 124 int n2 = SkFontStream::GetTableTags(stream, ttcIndex, array.get()); |
81 REPORTER_ASSERT(reporter, n == n2); | 125 REPORTER_ASSERT(reporter, n == n2); |
82 | 126 |
83 for (int i = 0; i < n; ++i) { | 127 for (int i = 0; i < n; ++i) { |
84 #ifdef DUMP_TTC_TABLES | 128 #ifdef DUMP_TTC_TABLES |
(...skipping 18 matching lines...) Expand all Loading... |
103 int count = SkFontStream::CountTTCEntries(stream); | 147 int count = SkFontStream::CountTTCEntries(stream); |
104 #ifdef DUMP_TTC_TABLES | 148 #ifdef DUMP_TTC_TABLES |
105 SkDebugf("CountTTCEntries %d\n", count); | 149 SkDebugf("CountTTCEntries %d\n", count); |
106 #endif | 150 #endif |
107 for (int i = 0; i < count; ++i) { | 151 for (int i = 0; i < count; ++i) { |
108 test_fontstream(reporter, stream, i); | 152 test_fontstream(reporter, stream, i); |
109 } | 153 } |
110 } | 154 } |
111 | 155 |
112 static void test_fontstream(skiatest::Reporter* reporter) { | 156 static void test_fontstream(skiatest::Reporter* reporter) { |
113 // TODO: replace when we get a tools/resources/fonts/test.ttc | 157 // This test cannot run if there is no resource path. |
114 const char* name = "/AmericanTypewriter.ttc"; | 158 SkString resourcePath = skiatest::Test::GetResourcePath(); |
115 SkFILEStream stream(name); | 159 if (resourcePath.isEmpty()) { |
| 160 SkDebugf("Could not run fontstream test because resourcePath not specifi
ed."); |
| 161 return; |
| 162 } |
| 163 SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "test.ttc"); |
| 164 |
| 165 SkFILEStream stream(filename.c_str()); |
116 if (stream.isValid()) { | 166 if (stream.isValid()) { |
117 test_fontstream(reporter, &stream); | 167 test_fontstream(reporter, &stream); |
| 168 } else { |
| 169 SkDebugf("Could not run fontstream test because test.ttc not found."); |
118 } | 170 } |
119 } | 171 } |
120 | 172 |
121 static void test_tables(skiatest::Reporter* reporter, SkTypeface* face) { | 173 static void test_tables(skiatest::Reporter* reporter, SkTypeface* face) { |
122 if (false) { // avoid bit rot, suppress warning | 174 if (false) { // avoid bit rot, suppress warning |
123 SkFontID fontID = face->uniqueID(); | 175 SkFontID fontID = face->uniqueID(); |
124 REPORTER_ASSERT(reporter, fontID); | 176 REPORTER_ASSERT(reporter, fontID); |
125 } | 177 } |
126 | 178 |
127 int count = face->countTables(); | 179 int count = face->countTables(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 214 } |
163 | 215 |
164 static void test_tables(skiatest::Reporter* reporter) { | 216 static void test_tables(skiatest::Reporter* reporter) { |
165 static const char* const gNames[] = { | 217 static const char* const gNames[] = { |
166 NULL, // default font | 218 NULL, // default font |
167 "Arial", "Times", "Times New Roman", "Helvetica", "Courier", | 219 "Arial", "Times", "Times New Roman", "Helvetica", "Courier", |
168 "Courier New", "Terminal", "MS Sans Serif", | 220 "Courier New", "Terminal", "MS Sans Serif", |
169 }; | 221 }; |
170 | 222 |
171 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) { | 223 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) { |
172 SkTypeface* face = SkTypeface::CreateFromName(gNames[i], | 224 SkAutoTUnref<SkTypeface> face(SkTypeface::CreateFromName(gNames[i], SkTy
peface::kNormal)); |
173 SkTypeface::kNormal); | |
174 if (face) { | 225 if (face) { |
175 #ifdef DUMP_TABLES | 226 #ifdef DUMP_TABLES |
176 SkDebugf("%s\n", gNames[i]); | 227 SkDebugf("%s\n", gNames[i]); |
177 #endif | 228 #endif |
178 test_tables(reporter, face); | 229 test_tables(reporter, face); |
179 test_unitsPerEm(reporter, face); | 230 test_unitsPerEm(reporter, face); |
180 test_countGlyphs(reporter, face); | 231 test_countGlyphs(reporter, face); |
181 face->unref(); | 232 test_charsToGlyphs(reporter, face); |
182 } | 233 } |
183 } | 234 } |
184 } | 235 } |
185 | 236 |
186 /* | 237 /* |
187 * Verifies that the advance values returned by generateAdvance and | 238 * Verifies that the advance values returned by generateAdvance and |
188 * generateMetrics match. | 239 * generateMetrics match. |
189 */ | 240 */ |
190 static void test_advances(skiatest::Reporter* reporter) { | 241 static void test_advances(skiatest::Reporter* reporter) { |
191 static const char* const faces[] = { | 242 static const char* const faces[] = { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 static void TestFontHost(skiatest::Reporter* reporter) { | 308 static void TestFontHost(skiatest::Reporter* reporter) { |
258 test_tables(reporter); | 309 test_tables(reporter); |
259 test_fontstream(reporter); | 310 test_fontstream(reporter); |
260 test_advances(reporter); | 311 test_advances(reporter); |
261 } | 312 } |
262 | 313 |
263 // need tests for SkStrSearch | 314 // need tests for SkStrSearch |
264 | 315 |
265 #include "TestClassDef.h" | 316 #include "TestClassDef.h" |
266 DEFINE_TESTCLASS("FontHost", FontHostTestClass, TestFontHost) | 317 DEFINE_TESTCLASS("FontHost", FontHostTestClass, TestFontHost) |
OLD | NEW |