OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 The Android Open Source Project | 2 * Copyright 2010 The Android Open Source Project |
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 "Resources.h" | 8 #include "Resources.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
11 #include "SkData.h" | 11 #include "SkData.h" |
12 #include "SkDocument.h" | 12 #include "SkDocument.h" |
13 #include "SkDeflate.h" | 13 #include "SkDeflate.h" |
14 #include "SkImageEncoder.h" | 14 #include "SkImageEncoder.h" |
15 #include "SkMatrix.h" | 15 #include "SkMatrix.h" |
16 #include "SkPDFCanon.h" | 16 #include "SkPDFCanon.h" |
17 #include "SkPDFDevice.h" | 17 #include "SkPDFDevice.h" |
18 #include "SkPDFFont.h" | 18 #include "SkPDFFont.h" |
19 #include "SkPDFStream.h" | 19 #include "SkPDFStream.h" |
20 #include "SkPDFTypes.h" | 20 #include "SkPDFTypes.h" |
| 21 #include "SkPDFUtils.h" |
21 #include "SkReadBuffer.h" | 22 #include "SkReadBuffer.h" |
22 #include "SkScalar.h" | 23 #include "SkScalar.h" |
23 #include "SkStream.h" | 24 #include "SkStream.h" |
24 #include "SkTypes.h" | 25 #include "SkTypes.h" |
25 #include "Test.h" | 26 #include "Test.h" |
26 #include "sk_tool_utils.h" | 27 #include "sk_tool_utils.h" |
27 | 28 |
28 #define DUMMY_TEXT "DCT compessed stream." | 29 #define DUMMY_TEXT "DCT compessed stream." |
29 | 30 |
30 namespace { | 31 namespace { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 SkPDFUnion boolTrue = SkPDFUnion::Bool(true); | 193 SkPDFUnion boolTrue = SkPDFUnion::Bool(true); |
193 ASSERT_EMIT_EQ(reporter, boolTrue, "true"); | 194 ASSERT_EMIT_EQ(reporter, boolTrue, "true"); |
194 | 195 |
195 SkPDFUnion boolFalse = SkPDFUnion::Bool(false); | 196 SkPDFUnion boolFalse = SkPDFUnion::Bool(false); |
196 ASSERT_EMIT_EQ(reporter, boolFalse, "false"); | 197 ASSERT_EMIT_EQ(reporter, boolFalse, "false"); |
197 | 198 |
198 SkPDFUnion int42 = SkPDFUnion::Int(42); | 199 SkPDFUnion int42 = SkPDFUnion::Int(42); |
199 ASSERT_EMIT_EQ(reporter, int42, "42"); | 200 ASSERT_EMIT_EQ(reporter, int42, "42"); |
200 | 201 |
201 SkPDFUnion realHalf = SkPDFUnion::Scalar(SK_ScalarHalf); | 202 SkPDFUnion realHalf = SkPDFUnion::Scalar(SK_ScalarHalf); |
202 ASSERT_EMIT_EQ(reporter, realHalf, "0.5"); | 203 ASSERT_EMIT_EQ(reporter, realHalf, ".5"); |
203 | 204 |
204 SkPDFUnion bigScalar = SkPDFUnion::Scalar(110999.75f); | 205 SkPDFUnion bigScalar = SkPDFUnion::Scalar(110999.75f); |
205 #if !defined(SK_ALLOW_LARGE_PDF_SCALARS) | |
206 ASSERT_EMIT_EQ(reporter, bigScalar, "111000"); | |
207 #else | |
208 ASSERT_EMIT_EQ(reporter, bigScalar, "110999.75"); | 206 ASSERT_EMIT_EQ(reporter, bigScalar, "110999.75"); |
209 | 207 |
210 SkPDFUnion biggerScalar = SkPDFUnion::Scalar(50000000.1); | 208 SkPDFUnion biggerScalar = SkPDFUnion::Scalar(50000000.1f); |
211 ASSERT_EMIT_EQ(reporter, biggerScalar, "50000000"); | 209 ASSERT_EMIT_EQ(reporter, biggerScalar, "50000000"); |
212 | 210 |
213 SkPDFUnion smallestScalar = SkPDFUnion::Scalar(1.0 / 65536); | 211 SkPDFUnion smallestScalar = SkPDFUnion::Scalar(1.0f / 65536); |
214 ASSERT_EMIT_EQ(reporter, smallestScalar, "0.00001526"); | 212 ASSERT_EMIT_EQ(reporter, smallestScalar, ".0000152587890"); |
215 #endif | |
216 | 213 |
217 SkPDFUnion stringSimple = SkPDFUnion::String("test ) string ( foo"); | 214 SkPDFUnion stringSimple = SkPDFUnion::String("test ) string ( foo"); |
218 ASSERT_EMIT_EQ(reporter, stringSimple, "(test \\) string \\( foo)"); | 215 ASSERT_EMIT_EQ(reporter, stringSimple, "(test \\) string \\( foo)"); |
219 | 216 |
220 SkString stringComplexInput("\ttest ) string ( foo"); | 217 SkString stringComplexInput("\ttest ) string ( foo"); |
221 SkPDFUnion stringComplex = SkPDFUnion::String(stringComplexInput); | 218 SkPDFUnion stringComplex = SkPDFUnion::String(stringComplexInput); |
222 ASSERT_EMIT_EQ(reporter, | 219 ASSERT_EMIT_EQ(reporter, |
223 stringComplex, | 220 stringComplex, |
224 "<0974657374202920737472696E67202820666F6F>"); | 221 "<0974657374202920737472696E67202820666F6F>"); |
225 | 222 |
(...skipping 15 matching lines...) Expand all Loading... |
241 } | 238 } |
242 | 239 |
243 static void TestPDFArray(skiatest::Reporter* reporter) { | 240 static void TestPDFArray(skiatest::Reporter* reporter) { |
244 SkAutoTUnref<SkPDFArray> array(new SkPDFArray); | 241 SkAutoTUnref<SkPDFArray> array(new SkPDFArray); |
245 ASSERT_EMIT_EQ(reporter, *array, "[]"); | 242 ASSERT_EMIT_EQ(reporter, *array, "[]"); |
246 | 243 |
247 array->appendInt(42); | 244 array->appendInt(42); |
248 ASSERT_EMIT_EQ(reporter, *array, "[42]"); | 245 ASSERT_EMIT_EQ(reporter, *array, "[42]"); |
249 | 246 |
250 array->appendScalar(SK_ScalarHalf); | 247 array->appendScalar(SK_ScalarHalf); |
251 ASSERT_EMIT_EQ(reporter, *array, "[42 0.5]"); | 248 ASSERT_EMIT_EQ(reporter, *array, "[42 .5]"); |
252 | 249 |
253 array->appendInt(0); | 250 array->appendInt(0); |
254 ASSERT_EMIT_EQ(reporter, *array, "[42 0.5 0]"); | 251 ASSERT_EMIT_EQ(reporter, *array, "[42 .5 0]"); |
255 | 252 |
256 array->appendBool(true); | 253 array->appendBool(true); |
257 ASSERT_EMIT_EQ(reporter, *array, "[42 0.5 0 true]"); | 254 ASSERT_EMIT_EQ(reporter, *array, "[42 .5 0 true]"); |
258 | 255 |
259 array->appendName("ThisName"); | 256 array->appendName("ThisName"); |
260 ASSERT_EMIT_EQ(reporter, *array, "[42 0.5 0 true /ThisName]"); | 257 ASSERT_EMIT_EQ(reporter, *array, "[42 .5 0 true /ThisName]"); |
261 | 258 |
262 array->appendName(SkString("AnotherName")); | 259 array->appendName(SkString("AnotherName")); |
263 ASSERT_EMIT_EQ(reporter, *array, "[42 0.5 0 true /ThisName /AnotherName]"); | 260 ASSERT_EMIT_EQ(reporter, *array, "[42 .5 0 true /ThisName /AnotherName]"); |
264 | 261 |
265 array->appendString("This String"); | 262 array->appendString("This String"); |
266 ASSERT_EMIT_EQ(reporter, *array, | 263 ASSERT_EMIT_EQ(reporter, *array, |
267 "[42 0.5 0 true /ThisName /AnotherName (This String)]"); | 264 "[42 .5 0 true /ThisName /AnotherName (This String)]"); |
268 | 265 |
269 array->appendString(SkString("Another String")); | 266 array->appendString(SkString("Another String")); |
270 ASSERT_EMIT_EQ(reporter, *array, | 267 ASSERT_EMIT_EQ(reporter, *array, |
271 "[42 0.5 0 true /ThisName /AnotherName (This String) " | 268 "[42 .5 0 true /ThisName /AnotherName (This String) " |
272 "(Another String)]"); | 269 "(Another String)]"); |
273 | 270 |
274 SkAutoTUnref<SkPDFArray> innerArray(new SkPDFArray); | 271 SkAutoTUnref<SkPDFArray> innerArray(new SkPDFArray); |
275 innerArray->appendInt(-1); | 272 innerArray->appendInt(-1); |
276 array->appendObject(innerArray.detach()); | 273 array->appendObject(innerArray.detach()); |
277 ASSERT_EMIT_EQ(reporter, *array, | 274 ASSERT_EMIT_EQ(reporter, *array, |
278 "[42 0.5 0 true /ThisName /AnotherName (This String) " | 275 "[42 .5 0 true /ThisName /AnotherName (This String) " |
279 "(Another String) [-1]]"); | 276 "(Another String) [-1]]"); |
280 | 277 |
281 SkAutoTUnref<SkPDFArray> referencedArray(new SkPDFArray); | 278 SkAutoTUnref<SkPDFArray> referencedArray(new SkPDFArray); |
282 Catalog catalog; | 279 Catalog catalog; |
283 catalog.numbers.addObject(referencedArray.get()); | 280 catalog.numbers.addObject(referencedArray.get()); |
284 REPORTER_ASSERT(reporter, catalog.numbers.getObjectNumber( | 281 REPORTER_ASSERT(reporter, catalog.numbers.getObjectNumber( |
285 referencedArray.get()) == 1); | 282 referencedArray.get()) == 1); |
286 array->appendObjRef(referencedArray.detach()); | 283 array->appendObjRef(referencedArray.detach()); |
287 | 284 |
288 SkString result = emit_to_string(*array, &catalog); | 285 SkString result = emit_to_string(*array, &catalog); |
289 ASSERT_EQ(reporter, result, | 286 ASSERT_EQ(reporter, result, |
290 "[42 0.5 0 true /ThisName /AnotherName (This String) " | 287 "[42 .5 0 true /ThisName /AnotherName (This String) " |
291 "(Another String) [-1] 1 0 R]"); | 288 "(Another String) [-1] 1 0 R]"); |
292 } | 289 } |
293 | 290 |
294 static void TestPDFDict(skiatest::Reporter* reporter) { | 291 static void TestPDFDict(skiatest::Reporter* reporter) { |
295 SkAutoTUnref<SkPDFDict> dict(new SkPDFDict); | 292 SkAutoTUnref<SkPDFDict> dict(new SkPDFDict); |
296 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); | 293 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); |
297 | 294 |
298 dict->insertInt("n1", SkToSizeT(42)); | 295 dict->insertInt("n1", SkToSizeT(42)); |
299 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42>>"); | 296 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42>>"); |
300 | 297 |
301 dict.reset(new SkPDFDict); | 298 dict.reset(new SkPDFDict); |
302 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); | 299 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); |
303 | 300 |
304 dict->insertInt("n1", 42); | 301 dict->insertInt("n1", 42); |
305 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42>>"); | 302 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42>>"); |
306 | 303 |
307 dict->insertScalar("n2", SK_ScalarHalf); | 304 dict->insertScalar("n2", SK_ScalarHalf); |
308 | 305 |
309 SkString n3("n3"); | 306 SkString n3("n3"); |
310 SkAutoTUnref<SkPDFArray> innerArray(new SkPDFArray); | 307 SkAutoTUnref<SkPDFArray> innerArray(new SkPDFArray); |
311 innerArray->appendInt(-100); | 308 innerArray->appendInt(-100); |
312 dict->insertObject(n3, innerArray.detach()); | 309 dict->insertObject(n3, innerArray.detach()); |
313 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42\n/n2 0.5\n/n3 [-100]>>"); | 310 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 42\n/n2 .5\n/n3 [-100]>>"); |
314 | 311 |
315 dict.reset(new SkPDFDict); | 312 dict.reset(new SkPDFDict); |
316 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); | 313 ASSERT_EMIT_EQ(reporter, *dict, "<<>>"); |
317 | 314 |
318 dict->insertInt("n1", 24); | 315 dict->insertInt("n1", 24); |
319 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24>>"); | 316 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24>>"); |
320 | 317 |
321 dict->insertInt("n2", SkToSizeT(99)); | 318 dict->insertInt("n2", SkToSizeT(99)); |
322 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99>>"); | 319 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99>>"); |
323 | 320 |
324 dict->insertScalar("n3", SK_ScalarHalf); | 321 dict->insertScalar("n3", SK_ScalarHalf); |
325 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 0.5>>"); | 322 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 .5>>"); |
326 | 323 |
327 dict->insertName("n4", "AName"); | 324 dict->insertName("n4", "AName"); |
328 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 0.5\n/n4 /AName>>"); | 325 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 .5\n/n4 /AName>>"); |
329 | 326 |
330 dict->insertName("n5", SkString("AnotherName")); | 327 dict->insertName("n5", SkString("AnotherName")); |
331 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 0.5\n/n4 /AName\n" | 328 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 .5\n/n4 /AName\n" |
332 "/n5 /AnotherName>>"); | 329 "/n5 /AnotherName>>"); |
333 | 330 |
334 dict->insertString("n6", "A String"); | 331 dict->insertString("n6", "A String"); |
335 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 0.5\n/n4 /AName\n" | 332 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 .5\n/n4 /AName\n" |
336 "/n5 /AnotherName\n/n6 (A String)>>"); | 333 "/n5 /AnotherName\n/n6 (A String)>>"); |
337 | 334 |
338 dict->insertString("n7", SkString("Another String")); | 335 dict->insertString("n7", SkString("Another String")); |
339 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 0.5\n/n4 /AName\n" | 336 ASSERT_EMIT_EQ(reporter, *dict, "<</n1 24\n/n2 99\n/n3 .5\n/n4 /AName\n" |
340 "/n5 /AnotherName\n/n6 (A String)\n/n7 (Another String)>>"); | 337 "/n5 /AnotherName\n/n6 (A String)\n/n7 (Another String)>>"); |
341 | 338 |
342 dict.reset(new SkPDFDict("DType")); | 339 dict.reset(new SkPDFDict("DType")); |
343 ASSERT_EMIT_EQ(reporter, *dict, "<</Type /DType>>"); | 340 ASSERT_EMIT_EQ(reporter, *dict, "<</Type /DType>>"); |
344 | 341 |
345 SkAutoTUnref<SkPDFArray> referencedArray(new SkPDFArray); | 342 SkAutoTUnref<SkPDFArray> referencedArray(new SkPDFArray); |
346 Catalog catalog; | 343 Catalog catalog; |
347 catalog.numbers.addObject(referencedArray.get()); | 344 catalog.numbers.addObject(referencedArray.get()); |
348 REPORTER_ASSERT(reporter, catalog.numbers.getObjectNumber( | 345 REPORTER_ASSERT(reporter, catalog.numbers.getObjectNumber( |
349 referencedArray.get()) == 1); | 346 referencedArray.get()) == 1); |
350 dict->insertObjRef("n1", referencedArray.detach()); | 347 dict->insertObjRef("n1", referencedArray.detach()); |
351 SkString result = emit_to_string(*dict, &catalog); | 348 SkString result = emit_to_string(*dict, &catalog); |
352 ASSERT_EQ(reporter, result, "<</Type /DType\n/n1 1 0 R>>"); | 349 ASSERT_EQ(reporter, result, "<</Type /DType\n/n1 1 0 R>>"); |
353 } | 350 } |
354 | 351 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 SkAutoTUnref<SkTypeface> noEmbedTypeface(GetResourceAsTypeface(resource)); | 425 SkAutoTUnref<SkTypeface> noEmbedTypeface(GetResourceAsTypeface(resource)); |
429 if (noEmbedTypeface) { | 426 if (noEmbedTypeface) { |
430 REPORTER_ASSERT(reporter, | 427 REPORTER_ASSERT(reporter, |
431 !SkPDFFont::CanEmbedTypeface(noEmbedTypeface, &canon)); | 428 !SkPDFFont::CanEmbedTypeface(noEmbedTypeface, &canon)); |
432 } | 429 } |
433 SkAutoTUnref<SkTypeface> portableTypeface( | 430 SkAutoTUnref<SkTypeface> portableTypeface( |
434 sk_tool_utils::create_portable_typeface(NULL, SkTypeface::kNormal)); | 431 sk_tool_utils::create_portable_typeface(NULL, SkTypeface::kNormal)); |
435 REPORTER_ASSERT(reporter, | 432 REPORTER_ASSERT(reporter, |
436 SkPDFFont::CanEmbedTypeface(portableTypeface, &canon)); | 433 SkPDFFont::CanEmbedTypeface(portableTypeface, &canon)); |
437 } | 434 } |
| 435 |
| 436 |
| 437 // test to see that all finite scalars round trip via scanf(). |
| 438 static void check_pdf_scalar_serialization( |
| 439 skiatest::Reporter* reporter, float inputFloat) { |
| 440 char floatString[SkPDFUtils::kMaximumFloatDecimalLength]; |
| 441 size_t len = SkPDFUtils::FloatToDecimal(inputFloat, floatString); |
| 442 if (len >= sizeof(floatString)) { |
| 443 ERRORF(reporter, "string too long: %u", (unsigned)len); |
| 444 return; |
| 445 } |
| 446 if (floatString[len] != '\0' || strlen(floatString) != len) { |
| 447 ERRORF(reporter, "terminator misplaced."); |
| 448 return; // The terminator is needed for sscanf(). |
| 449 } |
| 450 if (reporter->verbose()) { |
| 451 SkDebugf("%15.9g = \"%s\"\n", inputFloat, floatString); |
| 452 } |
| 453 float roundTripFloat; |
| 454 if (1 != sscanf(floatString, "%f", &roundTripFloat)) { |
| 455 ERRORF(reporter, "unscannable result: %s", floatString); |
| 456 return; |
| 457 } |
| 458 if (isfinite(inputFloat) && roundTripFloat != inputFloat) { |
| 459 ERRORF(reporter, "roundTripFloat (%.9g) != inputFloat (%.9g)", |
| 460 roundTripFloat, inputFloat); |
| 461 } |
| 462 } |
| 463 |
| 464 // Test SkPDFUtils::AppendScalar for accuracy. |
| 465 DEF_TEST(PDFPrimitives_Scalar, reporter) { |
| 466 SkRandom random(0x5EED); |
| 467 int iterationCount = 512; |
| 468 while (iterationCount-- > 0) { |
| 469 union { uint32_t u; float f; }; |
| 470 u = random.nextU(); |
| 471 static_assert(sizeof(float) == sizeof(uint32_t), ""); |
| 472 check_pdf_scalar_serialization(reporter, f); |
| 473 } |
| 474 float alwaysCheck[] = { |
| 475 0.0f, -0.0f, 1.0f, -1.0f, SK_ScalarPI, 0.1f, FLT_MIN, FLT_MAX, |
| 476 -FLT_MIN, -FLT_MAX, FLT_MIN / 16.0f, -FLT_MIN / 16.0f, |
| 477 SK_FloatNaN, SK_FloatInfinity, SK_FloatNegativeInfinity, |
| 478 -FLT_MIN / 8388608.0 |
| 479 }; |
| 480 for (float inputFloat: alwaysCheck) { |
| 481 check_pdf_scalar_serialization(reporter, inputFloat); |
| 482 } |
| 483 } |
OLD | NEW |