blob: 81d8c0a7b01d2d16438d16835f90cb9009cc2014 [file] [log] [blame]
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00001#include <string>
2
3#include "Test.h"
4#include "SkPDFCatalog.h"
5#include "SkPDFStream.h"
6#include "SkPDFTypes.h"
7#include "SkScalar.h"
8#include "SkStream.h"
9
10static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj,
11 const std::string& representation,
12 bool indirect) {
13 size_t directSize = obj->getOutputSize(NULL, false);
14 REPORTER_ASSERT(reporter, directSize == representation.size());
15
16 SkDynamicMemoryWStream buffer;
17 obj->emitObject(&buffer, NULL, false);
18 REPORTER_ASSERT(reporter, directSize == buffer.getOffset());
19 REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), representation.c_str(),
20 directSize) == 0);
21
22 if (indirect) {
23 // Indirect output.
24 static char header[] = "1 0 obj\n";
25 static size_t headerLen = strlen(header);
26 static char footer[] = "\nendobj\n";
27 static size_t footerLen = strlen(footer);
28
29 SkPDFCatalog catalog;
30 catalog.addObject(obj, false);
31
32 size_t indirectSize = obj->getOutputSize(&catalog, true);
33 REPORTER_ASSERT(reporter,
34 indirectSize == directSize + headerLen + footerLen);
35
36 buffer.reset();
37 obj->emitObject(&buffer, &catalog, true);
38 REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset());
39 REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), header,
40 headerLen) == 0);
41 REPORTER_ASSERT(reporter,
42 memcmp(buffer.getStream() + headerLen,
43 representation.c_str(), directSize) == 0);
44 REPORTER_ASSERT(reporter,
45 memcmp(buffer.getStream() + headerLen + directSize,
46 footer, footerLen) == 0);
47 }
48}
49
50static void TestCatalog(skiatest::Reporter* reporter) {
51 SkPDFCatalog catalog;
52 SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
53 int1->unref(); // SkRefPtr and new both took a reference.
54 SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
55 int2->unref(); // SkRefPtr and new both took a reference.
56 SkRefPtr<SkPDFInt> int3 = new SkPDFInt(3);
57 int3->unref(); // SkRefPtr and new both took a reference.
58 SkRefPtr<SkPDFInt> int1Again(int1.get());
59
60 catalog.addObject(int1.get(), false);
61 catalog.addObject(int2.get(), false);
62 catalog.addObject(int3.get(), false);
63
64 REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
65 REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
66 REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int3.get()) == 3);
67
68 SkDynamicMemoryWStream buffer;
69 catalog.emitObjectNumber(&buffer, int1.get());
70 catalog.emitObjectNumber(&buffer, int2.get());
71 catalog.emitObjectNumber(&buffer, int3.get());
72 catalog.emitObjectNumber(&buffer, int1Again.get());
73 char expectedResult[] = "1 02 03 01 0";
74 REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
75 strlen(expectedResult)) == 0);
76}
77
78static void TestObjectRef(skiatest::Reporter* reporter) {
79 SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
80 int1->unref(); // SkRefPtr and new both took a reference.
81 SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
82 int2->unref(); // SkRefPtr and new both took a reference.
83 SkRefPtr<SkPDFObjRef> int2ref = new SkPDFObjRef(int2.get());
84 int2ref->unref(); // SkRefPtr and new both took a reference.
85
86 SkPDFCatalog catalog;
87 catalog.addObject(int1.get(), false);
88 catalog.addObject(int2.get(), false);
89 REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
90 REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
91
92 char expectedResult[] = "2 0 R";
93 SkDynamicMemoryWStream buffer;
94 int2ref->emitObject(&buffer, &catalog, false);
95 REPORTER_ASSERT(reporter, buffer.getOffset() == strlen(expectedResult));
96 REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
97 buffer.getOffset()) == 0);
98}
99
100static void TestPDFPrimitives(skiatest::Reporter* reporter) {
101 SkRefPtr<SkPDFInt> int42 = new SkPDFInt(42);
102 int42->unref(); // SkRefPtr and new both took a reference.
103 CheckObjectOutput(reporter, int42.get(), "42", true);
104
105 SkRefPtr<SkPDFScalar> realHalf = new SkPDFScalar(SK_ScalarHalf);
106 realHalf->unref(); // SkRefPtr and new both took a reference.
107 CheckObjectOutput(reporter, realHalf.get(), "0.5", true);
108
109 SkRefPtr<SkPDFString> stringSimple = new SkPDFString("test ) string ( foo");
110 stringSimple->unref(); // SkRefPtr and new both took a reference.
111 CheckObjectOutput(reporter, stringSimple.get(), "(test \\) string \\( foo)",
112 true);
113 SkRefPtr<SkPDFString> stringComplex =
114 new SkPDFString("\ttest ) string ( foo");
115 stringComplex->unref(); // SkRefPtr and new both took a reference.
116 CheckObjectOutput(reporter, stringComplex.get(),
117 "<0974657374202920737472696E67202820666F6F>", true);
118
119 SkRefPtr<SkPDFName> name = new SkPDFName("Test name\twith#tab");
120 name->unref(); // SkRefPtr and new both took a reference.
121 CheckObjectOutput(reporter, name.get(), "/Test#20name#09with#23tab", false);
122
123 SkRefPtr<SkPDFArray> array = new SkPDFArray;
124 array->unref(); // SkRefPtr and new both took a reference.
125 CheckObjectOutput(reporter, array.get(), "[]", true);
126 array->append(int42.get());
127 CheckObjectOutput(reporter, array.get(), "[42]", true);
128 array->append(realHalf.get());
129 CheckObjectOutput(reporter, array.get(), "[42 0.5]", true);
130 SkRefPtr<SkPDFInt> int0 = new SkPDFInt(0);
131 int0->unref(); // SkRefPtr and new both took a reference.
132 array->append(int0.get());
133 CheckObjectOutput(reporter, array.get(), "[42 0.5 0]", true);
134 SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
135 int1->unref(); // SkRefPtr and new both took a reference.
136 array->setAt(0, int1.get());
137 CheckObjectOutput(reporter, array.get(), "[1 0.5 0]", true);
138
139 SkRefPtr<SkPDFDict> dict = new SkPDFDict;
140 dict->unref(); // SkRefPtr and new both took a reference.
141 CheckObjectOutput(reporter, dict.get(), "<<>>", true);
142 SkRefPtr<SkPDFName> n1 = new SkPDFName("n1");
143 n1->unref(); // SkRefPtr and new both took a reference.
144 dict->insert(n1.get(), int42.get());
145 CheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>", true);
146 SkRefPtr<SkPDFName> n2 = new SkPDFName("n2");
147 n2->unref(); // SkRefPtr and new both took a reference.
148 SkRefPtr<SkPDFName> n3 = new SkPDFName("n3");
149 n3->unref(); // SkRefPtr and new both took a reference.
150 dict->insert(n2.get(), realHalf.get());
151 dict->insert(n3.get(), array.get());
152 CheckObjectOutput(reporter, dict.get(),
153 "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>", true);
154
155 char streamBytes[] = "Test\nFoo\tBar";
156 SkRefPtr<SkMemoryStream> streamData = new SkMemoryStream(
157 streamBytes, strlen(streamBytes), true);
158 streamData->unref(); // SkRefPtr and new both took a reference.
159 SkRefPtr<SkPDFStream> stream = new SkPDFStream(streamData.get());
160 stream->unref(); // SkRefPtr and new both took a reference.
161 CheckObjectOutput(reporter, stream.get(),
162 "<</Length 12\n>> stream\nTest\nFoo\tBarendstream\n",
163 true);
164 stream->insert(n1.get(), int42.get());
165 CheckObjectOutput(reporter, stream.get(),
166 "<</Length 12\n/n1 42\n>> stream\nTest\nFoo\tBar"
167 "endstream\n",
168 true);
169
170 TestCatalog(reporter);
171
172 TestObjectRef(reporter);
173}
174
175#include "TestClassDef.h"
176DEFINE_TESTCLASS("PDFPrimitives", PDFPrimitivesTestClass, TestPDFPrimitives)