blob: 98d1864df1d4cea18cf4397d12fe54dc43403990 [file] [log] [blame]
halcanary8ee06f22015-08-11 10:30:12 -07001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
commit-bot@chromium.org8c908272013-10-22 14:49:03 +00007#include "Test.h"
commit-bot@chromium.org8c908272013-10-22 14:49:03 +00008
halcanary712fdf72015-12-10 08:59:43 -08009#include "Resources.h"
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000010#include "SkCanvas.h"
11#include "SkDocument.h"
12#include "SkOSFile.h"
13#include "SkStream.h"
halcanary712fdf72015-12-10 08:59:43 -080014#include "SkPixelSerializer.h"
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000015
16static void test_empty(skiatest::Reporter* reporter) {
17 SkDynamicMemoryWStream stream;
18
robertphillips@google.com701b4052013-11-18 16:26:25 +000019 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&stream));
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000020
21 doc->close();
22
23 REPORTER_ASSERT(reporter, stream.bytesWritten() == 0);
24}
25
26static void test_abort(skiatest::Reporter* reporter) {
27 SkDynamicMemoryWStream stream;
28 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&stream));
29
30 SkCanvas* canvas = doc->beginPage(100, 100);
31 canvas->drawColor(SK_ColorRED);
32 doc->endPage();
33
34 doc->abort();
35
halcanary50e82e62016-03-21 13:45:05 -070036 // Test that only the header is written, not the full document.
37 REPORTER_ASSERT(reporter, stream.bytesWritten() < 256);
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000038}
39
40static void test_abortWithFile(skiatest::Reporter* reporter) {
halcanary87f3ba42015-01-20 09:30:20 -080041 SkString tmpDir = skiatest::GetTmpDir();
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000042
43 if (tmpDir.isEmpty()) {
44 return; // TODO(edisonn): unfortunatelly this pattern is used in other
45 // tests, but if GetTmpDir() starts returning and empty dir
46 // allways, then all these tests will be disabled.
47 }
48
tfarinaa8e2e152014-07-28 19:26:58 -070049 SkString path = SkOSPath::Join(tmpDir.c_str(), "aborted.pdf");
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000050
51 // Make sure doc's destructor is called to flush.
52 {
53 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(path.c_str()));
54
55 SkCanvas* canvas = doc->beginPage(100, 100);
56 canvas->drawColor(SK_ColorRED);
57 doc->endPage();
58
59 doc->abort();
60 }
61
62 FILE* file = fopen(path.c_str(), "r");
63 // The created file should be empty.
64 char buffer[100];
65 REPORTER_ASSERT(reporter, fread(buffer, 1, 1, file) == 0);
66 fclose(file);
67}
68
69static void test_file(skiatest::Reporter* reporter) {
halcanary87f3ba42015-01-20 09:30:20 -080070 SkString tmpDir = skiatest::GetTmpDir();
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000071 if (tmpDir.isEmpty()) {
72 return; // TODO(edisonn): unfortunatelly this pattern is used in other
73 // tests, but if GetTmpDir() starts returning and empty dir
74 // allways, then all these tests will be disabled.
75 }
76
tfarinaa8e2e152014-07-28 19:26:58 -070077 SkString path = SkOSPath::Join(tmpDir.c_str(), "file.pdf");
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000078
79 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(path.c_str()));
80
81 SkCanvas* canvas = doc->beginPage(100, 100);
82
83 canvas->drawColor(SK_ColorRED);
84 doc->endPage();
85 doc->close();
86
87 FILE* file = fopen(path.c_str(), "r");
halcanary96fcdcc2015-08-27 07:41:13 -070088 REPORTER_ASSERT(reporter, file != nullptr);
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000089 char header[100];
edisonn@google.com5237b7f2013-10-22 18:33:21 +000090 REPORTER_ASSERT(reporter, fread(header, 4, 1, file) != 0);
commit-bot@chromium.org8c908272013-10-22 14:49:03 +000091 REPORTER_ASSERT(reporter, strncmp(header, "%PDF", 4) == 0);
92 fclose(file);
93}
94
95static void test_close(skiatest::Reporter* reporter) {
96 SkDynamicMemoryWStream stream;
97 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&stream));
98
99 SkCanvas* canvas = doc->beginPage(100, 100);
100 canvas->drawColor(SK_ColorRED);
101 doc->endPage();
102
103 doc->close();
104
105 REPORTER_ASSERT(reporter, stream.bytesWritten() != 0);
106}
107
108DEF_TEST(document_tests, reporter) {
halcanary2ccdb632015-08-11 13:35:12 -0700109 REQUIRE_PDF_DOCUMENT(document_tests, reporter);
commit-bot@chromium.org8c908272013-10-22 14:49:03 +0000110 test_empty(reporter);
111 test_abort(reporter);
112 test_abortWithFile(reporter);
113 test_file(reporter);
114 test_close(reporter);
115}
halcanary712fdf72015-12-10 08:59:43 -0800116
117namespace {
118class JPEGSerializer final : public SkPixelSerializer {
119 bool onUseEncodedData(const void*, size_t) override { return true; }
120 SkData* onEncode(const SkPixmap& pixmap) override {
121 SkBitmap bm;
122 return bm.installPixels(pixmap.info(),
123 pixmap.writable_addr(),
124 pixmap.rowBytes(),
125 pixmap.ctable(),
126 nullptr, nullptr)
127 ? SkImageEncoder::EncodeData(bm, SkImageEncoder::kJPEG_Type, 85)
128 : nullptr;
129 }
130};
131} // namespace
132
133size_t count_bytes(const SkBitmap& bm, bool useDCT) {
134 SkDynamicMemoryWStream stream;
135 SkAutoTUnref<SkDocument> doc;
136 if (useDCT) {
137 SkAutoTUnref<SkPixelSerializer> serializer(new JPEGSerializer);
138 doc.reset(SkDocument::CreatePDF(
139 &stream, SK_ScalarDefaultRasterDPI, serializer));
140 } else {
141 doc.reset(SkDocument::CreatePDF(&stream));
142 }
143 SkCanvas* canvas = doc->beginPage(64, 64);
144 canvas->drawBitmap(bm, 0, 0);
145 doc->endPage();
146 doc->close();
147 return stream.bytesWritten();
148}
149
150DEF_TEST(document_dct_encoder, r) {
151 REQUIRE_PDF_DOCUMENT(document_dct_encoder, r);
152 SkBitmap bm;
153 if (GetResourceAsBitmap("mandrill_64.png", &bm)) {
154 // Lossy encoding works better on photographs.
155 REPORTER_ASSERT(r, count_bytes(bm, true) < count_bytes(bm, false));
156 }
157}
halcanary53b1c092016-01-06 09:02:25 -0800158
159DEF_TEST(document_skbug_4734, r) {
160 REQUIRE_PDF_DOCUMENT(document_skbug_4734, r);
161 SkDynamicMemoryWStream stream;
162 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&stream));
163 SkCanvas* canvas = doc->beginPage(64, 64);
164 canvas->scale(10000.0f, 10000.0f);
165 canvas->translate(20.0f, 10.0f);
166 canvas->rotate(30.0f);
167 const char text[] = "HELLO";
168 canvas->drawText(text, strlen(text), 0, 0, SkPaint());
169}