1 /*
2 * Copyright 2020 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 */
7 #include "tests/Test.h"
8
9 #ifdef SK_SUPPORT_PDF
10
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkFont.h"
13 #include "include/core/SkStream.h"
14 #include "include/docs/SkPDFDocument.h"
15
16 using PDFTag = SkPDF::StructureElementNode;
17
18 // Test building a tagged PDF where nodes are pruned.
19 // Add this to args.gn to output the PDF to a file:
20 // extra_cflags = [ "-DSK_PDF_TEST_TAGS_OUTPUT_PATH=\"/tmp/pruning.pdf\"" ]
DEF_TEST(SkPDF_tagged_pruning,r)21 DEF_TEST(SkPDF_tagged_pruning, r) {
22 REQUIRE_PDF_DOCUMENT(SkPDF_tagged, r);
23 #ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
24 SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
25 #else
26 SkDynamicMemoryWStream outputStream;
27 #endif
28
29 SkSize pageSize = SkSize::Make(612, 792); // U.S. Letter
30
31 SkPDF::Metadata metadata;
32 metadata.fTitle = "Example Tagged PDF";
33 metadata.fCreator = "Skia";
34 SkTime::DateTime now;
35 SkTime::GetDateTime(&now);
36 metadata.fCreation = now;
37 metadata.fModified = now;
38
39 // The document tag.
40 auto root = std::make_unique<PDFTag>();
41 root->fNodeId = 1;
42 root->fTypeString = "Document";
43 root->fLang = "en-US";
44
45 // First paragraph.
46 auto p1 = std::make_unique<PDFTag>();
47 p1->fNodeId = 2;
48 p1->fAdditionalNodeIds = {3, 4};
49 p1->fTypeString = "P";
50 root->fChildVector.push_back(std::move(p1));
51
52 // Second paragraph.
53 auto p2 = std::make_unique<PDFTag>();
54 p2->fNodeId = 5;
55 p2->fAdditionalNodeIds = {6, 7};
56 p2->fTypeString = "P";
57 root->fChildVector.push_back(std::move(p2));
58
59 metadata.fStructureElementTreeRoot = root.get();
60 sk_sp<SkDocument> document = SkPDF::MakeDocument(
61 &outputStream, metadata);
62
63 SkPaint paint;
64 paint.setColor(SK_ColorBLACK);
65
66 SkCanvas* canvas =
67 document->beginPage(pageSize.width(),
68 pageSize.height());
69 SkFont font(nullptr, 20);
70 SkPDF::SetNodeId(canvas, 3);
71 canvas->drawString("First paragraph line 1", 72, 72, font, paint);
72 SkPDF::SetNodeId(canvas, 4);
73 canvas->drawString("First paragraph line 2", 72, 108, font, paint);
74 SkPDF::SetNodeId(canvas, 6);
75 canvas->drawString("Second paragraph line 1", 72, 180, font, paint);
76 SkPDF::SetNodeId(canvas, 7);
77 canvas->drawString("Second paragraph line 2", 72, 216, font, paint);
78
79 document->endPage();
80 document->close();
81 outputStream.flush();
82 }
83
84 // Similar to SkPDF_tagged_pruning but never actually writes out anything annotated.
85 // Ensures that nothing goes wring when there are no annotations on an annotated PDF.
DEF_TEST(SkPDF_tagged_pruning_empty,r)86 DEF_TEST(SkPDF_tagged_pruning_empty, r) {
87 REQUIRE_PDF_DOCUMENT(SkPDF_tagged, r);
88 #ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
89 SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
90 #else
91 SkDynamicMemoryWStream outputStream;
92 #endif
93
94 SkSize pageSize = SkSize::Make(612, 792); // U.S. Letter
95
96 SkPDF::Metadata metadata;
97 metadata.fTitle = "Example Tagged PDF";
98 metadata.fCreator = "Skia";
99 SkTime::DateTime now;
100 SkTime::GetDateTime(&now);
101 metadata.fCreation = now;
102 metadata.fModified = now;
103
104 // The document tag.
105 auto root = std::make_unique<PDFTag>();
106 root->fNodeId = 1;
107 root->fTypeString = "Document";
108 root->fLang = "en-US";
109
110 // First paragraph.
111 auto p1 = std::make_unique<PDFTag>();
112 p1->fNodeId = 2;
113 p1->fAdditionalNodeIds = {3, 4};
114 p1->fTypeString = "P";
115 root->fChildVector.push_back(std::move(p1));
116
117 // Second paragraph.
118 auto p2 = std::make_unique<PDFTag>();
119 p2->fNodeId = 5;
120 p2->fAdditionalNodeIds = {6, 7};
121 p2->fTypeString = "P";
122 root->fChildVector.push_back(std::move(p2));
123
124 metadata.fStructureElementTreeRoot = root.get();
125 sk_sp<SkDocument> document = SkPDF::MakeDocument(
126 &outputStream, metadata);
127
128 SkPaint paint;
129 paint.setColor(SK_ColorBLACK);
130
131 SkCanvas* canvas =
132 document->beginPage(pageSize.width(),
133 pageSize.height());
134
135 canvas->drawRect(SkRect::MakeXYWH(10, 10, 100, 100), paint);
136
137 document->endPage();
138 document->close();
139 outputStream.flush();
140 }
141
142 #endif
143