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