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