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