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 "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkData.h" | 10 #include "SkData.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 void addResource(SkPDFObject* object) { | 34 void addResource(SkPDFObject* object) { |
35 fResources.append(1, &object); | 35 fResources.append(1, &object); |
36 } | 36 } |
37 | 37 |
38 private: | 38 private: |
39 SkTDArray<SkPDFObject*> fResources; | 39 SkTDArray<SkPDFObject*> fResources; |
40 }; | 40 }; |
41 | 41 |
42 #define DUMMY_TEXT "DCT compessed stream." | 42 #define DUMMY_TEXT "DCT compessed stream." |
43 | 43 |
44 static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap
) { | |
45 *pixelRefOffset = 0; | |
46 return SkData::NewWithProc(DUMMY_TEXT, sizeof(DUMMY_TEXT) - 1, NULL, NULL); | |
47 } | |
48 | |
49 static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, | 44 static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, |
50 const void* buffer, size_t len) { | 45 const void* buffer, size_t len) { |
51 SkAutoDataUnref data(stream.copyToData()); | 46 SkAutoDataUnref data(stream.copyToData()); |
52 if (offset + len > data->size()) { | 47 if (offset + len > data->size()) { |
53 return false; | 48 return false; |
54 } | 49 } |
55 return memcmp(data->bytes() + offset, buffer, len) == 0; | 50 return memcmp(data->bytes() + offset, buffer, len) == 0; |
56 } | 51 } |
57 | 52 |
58 static bool stream_contains(const SkDynamicMemoryWStream& stream, | |
59 const char* buffer) { | |
60 SkAutoDataUnref data(stream.copyToData()); | |
61 size_t len = strlen(buffer); // our buffer does not have EOSs. | |
62 | |
63 for (size_t offset = 0 ; offset < data->size() - len; offset++) { | |
64 if (memcmp(data->bytes() + offset, buffer, len) == 0) { | |
65 return true; | |
66 } | |
67 } | |
68 | |
69 return false; | |
70 } | |
71 | |
72 static void emit_object(SkPDFObject* object, | 53 static void emit_object(SkPDFObject* object, |
73 SkWStream* stream, | 54 SkWStream* stream, |
74 SkPDFCatalog* catalog, | 55 SkPDFCatalog* catalog, |
75 bool indirect) { | 56 bool indirect) { |
76 SkPDFObject* realObject = catalog->getSubstituteObject(object); | 57 SkPDFObject* realObject = catalog->getSubstituteObject(object); |
77 if (indirect) { | 58 if (indirect) { |
78 stream->writeDecAsText(catalog->getObjectNumber(object)); | 59 stream->writeDecAsText(catalog->getObjectNumber(object)); |
79 stream->writeText(" 0 obj\n"); // Generation number is always 0. | 60 stream->writeText(" 0 obj\n"); // Generation number is always 0. |
80 realObject->emitObject(stream, catalog); | 61 realObject->emitObject(stream, catalog); |
81 stream->writeText("\nendobj\n"); | 62 stream->writeText("\nendobj\n"); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 stub->insert("Value", new SkPDFInt(44))->unref(); | 217 stub->insert("Value", new SkPDFInt(44))->unref(); |
237 | 218 |
238 SkPDFCatalog catalog((SkPDFDocument::Flags)0); | 219 SkPDFCatalog catalog((SkPDFDocument::Flags)0); |
239 catalog.addObject(proxy.get(), false); | 220 catalog.addObject(proxy.get(), false); |
240 catalog.setSubstitute(proxy.get(), stub.get()); | 221 catalog.setSubstitute(proxy.get(), stub.get()); |
241 | 222 |
242 REPORTER_ASSERT(reporter, stub.get() == catalog.getSubstituteObject(proxy)); | 223 REPORTER_ASSERT(reporter, stub.get() == catalog.getSubstituteObject(proxy)); |
243 REPORTER_ASSERT(reporter, proxy.get() != catalog.getSubstituteObject(stub)); | 224 REPORTER_ASSERT(reporter, proxy.get() != catalog.getSubstituteObject(stub)); |
244 } | 225 } |
245 | 226 |
246 // Create a bitmap that would be very eficiently compressed in a ZIP. | |
247 static void setup_bitmap(SkBitmap* bitmap, int width, int height) { | |
248 bitmap->allocN32Pixels(width, height); | |
249 bitmap->eraseColor(SK_ColorWHITE); | |
250 } | |
251 | |
252 static void TestImage(skiatest::Reporter* reporter, const SkBitmap& bitmap, | |
253 const char* expected, bool useDCTEncoder) { | |
254 SkISize pageSize = SkISize::Make(bitmap.width(), bitmap.height()); | |
255 SkAutoTUnref<SkPDFDevice> dev(new SkPDFDevice(pageSize, pageSize, SkMatrix::
I())); | |
256 | |
257 if (useDCTEncoder) { | |
258 dev->setDCTEncoder(encode_to_dct_data); | |
259 } | |
260 | |
261 SkCanvas c(dev); | |
262 c.drawBitmap(bitmap, 0, 0, NULL); | |
263 | |
264 SkPDFDocument doc; | |
265 doc.appendPage(dev); | |
266 | |
267 SkDynamicMemoryWStream stream; | |
268 doc.emitPDF(&stream); | |
269 | |
270 REPORTER_ASSERT(reporter, stream_contains(stream, expected)); | |
271 } | |
272 | |
273 static void TestUncompressed(skiatest::Reporter* reporter) { | |
274 SkBitmap bitmap; | |
275 setup_bitmap(&bitmap, 1, 1); | |
276 TestImage(reporter, bitmap, | |
277 "/Subtype /Image\n" | |
278 "/Width 1\n" | |
279 "/Height 1\n" | |
280 "/ColorSpace /DeviceRGB\n" | |
281 "/BitsPerComponent 8\n" | |
282 "/Length 3\n" | |
283 ">> stream", | |
284 true); | |
285 } | |
286 | |
287 static void TestFlateDecode(skiatest::Reporter* reporter) { | |
288 #ifndef SK_NO_FLATE | |
289 SkBitmap bitmap; | |
290 setup_bitmap(&bitmap, 10, 10); | |
291 TestImage(reporter, bitmap, | |
292 "/Subtype /Image\n" | |
293 "/Width 10\n" | |
294 "/Height 10\n" | |
295 "/ColorSpace /DeviceRGB\n" | |
296 "/BitsPerComponent 8\n" | |
297 "/Filter /FlateDecode\n" | |
298 "/Length 13\n" | |
299 ">> stream", | |
300 false); | |
301 #endif // SK_NO_FLATE | |
302 } | |
303 | |
304 static void TestDCTDecode(skiatest::Reporter* reporter) { | |
305 SkBitmap bitmap; | |
306 setup_bitmap(&bitmap, 32, 32); | |
307 TestImage(reporter, bitmap, | |
308 "/Subtype /Image\n" | |
309 "/Width 32\n" | |
310 "/Height 32\n" | |
311 "/ColorSpace /DeviceRGB\n" | |
312 "/BitsPerComponent 8\n" | |
313 "/Filter /DCTDecode\n" | |
314 "/ColorTransform 0\n" | |
315 "/Length 21\n" | |
316 ">> stream", | |
317 true); | |
318 } | |
319 | |
320 static void TestImages(skiatest::Reporter* reporter) { | |
321 TestUncompressed(reporter); | |
322 TestFlateDecode(reporter); | |
323 TestDCTDecode(reporter); | |
324 } | |
325 | |
326 // This test used to assert without the fix submitted for | 227 // This test used to assert without the fix submitted for |
327 // http://code.google.com/p/skia/issues/detail?id=1083. | 228 // http://code.google.com/p/skia/issues/detail?id=1083. |
328 // SKP files might have invalid glyph ids. This test ensures they are ignored, | 229 // SKP files might have invalid glyph ids. This test ensures they are ignored, |
329 // and there is no assert on input data in Debug mode. | 230 // and there is no assert on input data in Debug mode. |
330 static void test_issue1083() { | 231 static void test_issue1083() { |
331 SkISize pageSize = SkISize::Make(100, 100); | 232 SkISize pageSize = SkISize::Make(100, 100); |
332 SkAutoTUnref<SkPDFDevice> dev(new SkPDFDevice(pageSize, pageSize, SkMatrix::
I())); | 233 SkAutoTUnref<SkPDFDevice> dev(new SkPDFDevice(pageSize, pageSize, SkMatrix::
I())); |
333 | 234 |
334 SkCanvas c(dev); | 235 SkCanvas c(dev); |
335 SkPaint paint; | 236 SkPaint paint; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 320 |
420 TestPDFStream(reporter); | 321 TestPDFStream(reporter); |
421 | 322 |
422 TestCatalog(reporter); | 323 TestCatalog(reporter); |
423 | 324 |
424 TestObjectRef(reporter); | 325 TestObjectRef(reporter); |
425 | 326 |
426 TestSubstitute(reporter); | 327 TestSubstitute(reporter); |
427 | 328 |
428 test_issue1083(); | 329 test_issue1083(); |
429 | |
430 TestImages(reporter); | |
431 } | 330 } |
432 | 331 |
433 namespace { | 332 namespace { |
434 | 333 |
435 class DummyImageFilter : public SkImageFilter { | 334 class DummyImageFilter : public SkImageFilter { |
436 public: | 335 public: |
437 DummyImageFilter(bool visited = false) : SkImageFilter(0, NULL), fVisited(vi
sited) {} | 336 DummyImageFilter(bool visited = false) : SkImageFilter(0, NULL), fVisited(vi
sited) {} |
438 ~DummyImageFilter() SK_OVERRIDE {} | 337 ~DummyImageFilter() SK_OVERRIDE {} |
439 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, | 338 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, |
440 SkBitmap* result, SkIPoint* offset) const SK_OVER
RIDE { | 339 SkBitmap* result, SkIPoint* offset) const SK_OVER
RIDE { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 375 |
477 // Filter just created; should be unvisited. | 376 // Filter just created; should be unvisited. |
478 REPORTER_ASSERT(reporter, !filter->visited()); | 377 REPORTER_ASSERT(reporter, !filter->visited()); |
479 SkPaint paint; | 378 SkPaint paint; |
480 paint.setImageFilter(filter.get()); | 379 paint.setImageFilter(filter.get()); |
481 canvas.drawRect(SkRect::MakeWH(100, 100), paint); | 380 canvas.drawRect(SkRect::MakeWH(100, 100), paint); |
482 | 381 |
483 // Filter was used in rendering; should be visited. | 382 // Filter was used in rendering; should be visited. |
484 REPORTER_ASSERT(reporter, filter->visited()); | 383 REPORTER_ASSERT(reporter, filter->visited()); |
485 } | 384 } |
OLD | NEW |