| 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 |