1 // Copyright 2017 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/fxcrt/check.h"
6 #include "core/fxcrt/fx_system.h"
7 #include "core/fxge/cfx_defaultrenderdevice.h"
8 #include "public/fpdf_edit.h"
9 #include "testing/embedder_test.h"
10 #include "testing/embedder_test_constants.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 using pdfium::RectanglesChecksum;
14
15 using FPDFEditPathEmbedderTest = EmbedderTest;
16
17 namespace {
18
19 constexpr int kExpectedRectangleWidth = 200;
20 constexpr int kExpectedRectangleHeight = 300;
21
RectanglesAndTriangleChecksum()22 const char* RectanglesAndTriangleChecksum() {
23 return CFX_DefaultRenderDevice::UseSkiaRenderer()
24 ? "89b85ca2749a98320518531cf365b010"
25 : "8bb78ca28f1e0ab9d36c0745ae0f58bb";
26 }
27
CreateBlackTriangle()28 ScopedFPDFPageObject CreateBlackTriangle() {
29 ScopedFPDFPageObject path(FPDFPageObj_CreateNewPath(100, 50));
30 EXPECT_TRUE(FPDFPageObj_SetFillColor(path.get(), 0, 0, 0, 255));
31 EXPECT_TRUE(FPDFPath_SetDrawMode(path.get(), FPDF_FILLMODE_ALTERNATE, 0));
32 EXPECT_TRUE(FPDFPath_LineTo(path.get(), 100, 75));
33 EXPECT_TRUE(FPDFPath_LineTo(path.get(), 75, 75));
34 EXPECT_TRUE(FPDFPath_Close(path.get()));
35 return path;
36 }
37
38 } // namespace
39
TEST_F(FPDFEditPathEmbedderTest,VerifyCorrectColoursReturned)40 TEST_F(FPDFEditPathEmbedderTest, VerifyCorrectColoursReturned) {
41 constexpr int kObjectCount = 256;
42 CreateEmptyDocument();
43 FPDF_PAGE page = FPDFPage_New(document(), 0, 612, 792);
44
45 for (size_t i = 0; i < kObjectCount; ++i) {
46 FPDF_PAGEOBJECT path = FPDFPageObj_CreateNewPath(400, 100);
47 EXPECT_TRUE(FPDFPageObj_SetFillColor(path, i, i, i, i));
48 EXPECT_TRUE(FPDFPageObj_SetStrokeColor(path, i, i, i, i));
49 EXPECT_TRUE(FPDFPath_SetDrawMode(path, FPDF_FILLMODE_ALTERNATE, 0));
50 EXPECT_TRUE(FPDFPath_LineTo(path, 400, 200));
51 EXPECT_TRUE(FPDFPath_LineTo(path, 300, 100));
52 EXPECT_TRUE(FPDFPath_Close(path));
53
54 FPDFPage_InsertObject(page, path);
55 }
56
57 EXPECT_TRUE(FPDFPage_GenerateContent(page));
58 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
59 FPDF_ClosePage(page);
60 page = nullptr;
61
62 ASSERT_TRUE(OpenSavedDocument());
63 page = LoadSavedPage(0);
64 ASSERT_TRUE(page);
65
66 for (size_t i = 0; i < kObjectCount; ++i) {
67 FPDF_PAGEOBJECT path = FPDFPage_GetObject(page, i);
68 ASSERT_TRUE(path);
69
70 EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
71
72 unsigned int r;
73 unsigned int g;
74 unsigned int b;
75 unsigned int a;
76 ASSERT_TRUE(FPDFPageObj_GetFillColor(path, &r, &g, &b, &a));
77 EXPECT_EQ(i, r);
78 EXPECT_EQ(i, g);
79 EXPECT_EQ(i, b);
80 EXPECT_EQ(i, a);
81
82 ASSERT_TRUE(FPDFPageObj_GetStrokeColor(path, &r, &g, &b, &a));
83 EXPECT_EQ(i, r);
84 EXPECT_EQ(i, g);
85 EXPECT_EQ(i, b);
86 EXPECT_EQ(i, a);
87 }
88
89 CloseSavedPage(page);
90 CloseSavedDocument();
91 }
92
TEST_F(FPDFEditPathEmbedderTest,GetAndSetMatrixForPath)93 TEST_F(FPDFEditPathEmbedderTest, GetAndSetMatrixForPath) {
94 OpenDocument("rectangles_double_flipped.pdf");
95 ScopedEmbedderTestPage page = LoadScopedPage(0);
96 ASSERT_TRUE(page);
97
98 {
99 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
100 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
101 kExpectedRectangleHeight, RectanglesChecksum());
102 }
103
104 FPDF_PAGEOBJECT path = FPDFPage_GetObject(page.get(), 0);
105 ASSERT_TRUE(path);
106 ASSERT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
107
108 FS_MATRIX matrix;
109 ASSERT_TRUE(FPDFPageObj_GetMatrix(path, &matrix));
110 EXPECT_FLOAT_EQ(1.0f, matrix.a);
111 EXPECT_FLOAT_EQ(0.0f, matrix.b);
112 EXPECT_FLOAT_EQ(0.0f, matrix.c);
113 EXPECT_FLOAT_EQ(-1.0f, matrix.d);
114 EXPECT_FLOAT_EQ(0.0f, matrix.e);
115 EXPECT_FLOAT_EQ(300.0f, matrix.f);
116
117 ASSERT_TRUE(FPDFPageObj_SetMatrix(path, &matrix));
118 {
119 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
120 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
121 kExpectedRectangleHeight, RectanglesChecksum());
122 }
123
124 ASSERT_TRUE(FPDFPage_GenerateContent(page.get()));
125 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
126
127 {
128 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
129 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
130 kExpectedRectangleHeight, RectanglesChecksum());
131 }
132
133
134 VerifySavedDocument(kExpectedRectangleWidth, kExpectedRectangleHeight,
135 RectanglesChecksum());
136 }
137
TEST_F(FPDFEditPathEmbedderTest,GetAndSetMatrixForFormWithPath)138 TEST_F(FPDFEditPathEmbedderTest, GetAndSetMatrixForFormWithPath) {
139 OpenDocument("form_object_with_path.pdf");
140 ScopedEmbedderTestPage page = LoadScopedPage(0);
141 ASSERT_TRUE(page);
142
143 {
144 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
145 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
146 kExpectedRectangleHeight, RectanglesChecksum());
147 }
148
149 FPDF_PAGEOBJECT form = FPDFPage_GetObject(page.get(), 0);
150 ASSERT_TRUE(form);
151 ASSERT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(form));
152
153 FS_MATRIX matrix;
154 ASSERT_TRUE(FPDFPageObj_GetMatrix(form, &matrix));
155 EXPECT_FLOAT_EQ(2.0f, matrix.a);
156 EXPECT_FLOAT_EQ(0.0f, matrix.b);
157 EXPECT_FLOAT_EQ(0.0f, matrix.c);
158 EXPECT_FLOAT_EQ(-1.0f, matrix.d);
159 EXPECT_FLOAT_EQ(0.0f, matrix.e);
160 EXPECT_FLOAT_EQ(300.0f, matrix.f);
161
162 ASSERT_TRUE(FPDFPageObj_SetMatrix(form, &matrix));
163 {
164 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
165 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
166 kExpectedRectangleHeight, RectanglesChecksum());
167 }
168
169 FPDF_PAGEOBJECT path = FPDFFormObj_GetObject(form, 0);
170 ASSERT_TRUE(path);
171 ASSERT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path));
172
173 ASSERT_TRUE(FPDFPageObj_GetMatrix(path, &matrix));
174 EXPECT_FLOAT_EQ(0.5f, matrix.a);
175 EXPECT_FLOAT_EQ(0.0f, matrix.b);
176 EXPECT_FLOAT_EQ(0.0f, matrix.c);
177 EXPECT_FLOAT_EQ(-1.0f, matrix.d);
178 EXPECT_FLOAT_EQ(0.0f, matrix.e);
179 EXPECT_FLOAT_EQ(300.0f, matrix.f);
180
181 ASSERT_TRUE(FPDFPageObj_SetMatrix(path, &matrix));
182 {
183 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
184 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
185 kExpectedRectangleHeight, RectanglesChecksum());
186 }
187
188 ASSERT_TRUE(FPDFPage_GenerateContent(page.get()));
189 ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
190
191 {
192 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
193 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
194 kExpectedRectangleHeight, RectanglesChecksum());
195 }
196
197
198 VerifySavedDocument(kExpectedRectangleWidth, kExpectedRectangleHeight,
199 RectanglesChecksum());
200 }
201
TEST_F(FPDFEditPathEmbedderTest,AddPathToRectangles)202 TEST_F(FPDFEditPathEmbedderTest, AddPathToRectangles) {
203 OpenDocument("rectangles.pdf");
204 ScopedEmbedderTestPage page = LoadScopedPage(0);
205 ASSERT_TRUE(page);
206
207 {
208 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
209 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
210 kExpectedRectangleHeight, RectanglesChecksum());
211 }
212
213 ScopedFPDFPageObject path = CreateBlackTriangle();
214 ASSERT_TRUE(path);
215 FPDFPage_InsertObject(page.get(), path.release());
216
217 {
218 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
219 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
220 kExpectedRectangleHeight, RectanglesAndTriangleChecksum());
221 }
222
223 EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
224 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
225
226 {
227 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
228 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
229 kExpectedRectangleHeight, RectanglesAndTriangleChecksum());
230 }
231
232
233 VerifySavedDocument(kExpectedRectangleWidth, kExpectedRectangleHeight,
234 RectanglesAndTriangleChecksum());
235 }
236
TEST_F(FPDFEditPathEmbedderTest,AddPathToRectanglesWithLeakyCTM)237 TEST_F(FPDFEditPathEmbedderTest, AddPathToRectanglesWithLeakyCTM) {
238 OpenDocument("rectangles_with_leaky_ctm.pdf");
239 ScopedEmbedderTestPage page = LoadScopedPage(0);
240 ASSERT_TRUE(page);
241
242 {
243 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
244 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
245 kExpectedRectangleHeight, RectanglesChecksum());
246 }
247
248 ScopedFPDFPageObject path = CreateBlackTriangle();
249 ASSERT_TRUE(path);
250 FPDFPage_InsertObject(page.get(), path.release());
251
252 {
253 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
254 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
255 kExpectedRectangleHeight, RectanglesAndTriangleChecksum());
256 }
257
258 EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
259 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
260
261 {
262 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
263 CompareBitmap(bitmap.get(), kExpectedRectangleWidth,
264 kExpectedRectangleHeight, RectanglesAndTriangleChecksum());
265 }
266
267
268 VerifySavedDocument(kExpectedRectangleWidth, kExpectedRectangleHeight,
269 RectanglesAndTriangleChecksum());
270 }
271