Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PDFTaggedTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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 */
8
9#ifdef SK_SUPPORT_PDF
14#include "include/core/SkFont.h"
15#include "include/core/SkImage.h" // IWYU pragma: keep
18#include "include/core/SkSize.h"
23#include "src/pdf/SkPDFUtils.h"
24#include "tests/Test.h"
26
27#include <memory>
28#include <utility>
29#include <vector>
30
31using PDFTag = SkPDF::StructureElementNode;
32
33// Test building a tagged PDF.
34// Add this to args.gn to output the PDF to a file:
35// extra_cflags = [ "-DSK_PDF_TEST_TAGS_OUTPUT_PATH=\"/tmp/foo.pdf\"" ]
36DEF_TEST(SkPDF_tagged_doc, r) {
37 REQUIRE_PDF_DOCUMENT(SkPDF_tagged_doc, r);
38#ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
39 SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
40#else
41 SkDynamicMemoryWStream outputStream;
42#endif
43
44 SkSize pageSize = SkSize::Make(612, 792); // U.S. Letter
45
46 SkPDF::Metadata metadata;
47 metadata.fTitle = "Example Tagged PDF";
48 metadata.fCreator = "Skia";
52 metadata.fCreation = now;
53 metadata.fModified = now;
54
55 // The document tag.
56 auto root = std::make_unique<PDFTag>();
57 root->fNodeId = 1;
58 root->fTypeString = "Document";
59
60 // Heading.
61 auto h1 = std::make_unique<PDFTag>();
62 h1->fNodeId = 2;
63 h1->fTypeString = "H1";
64 h1->fAlt = "A Header";
65 root->fChildVector.push_back(std::move(h1));
66
67 // Initial paragraph.
68 auto p = std::make_unique<PDFTag>();
69 p->fNodeId = 3;
70 p->fTypeString = "P";
71 root->fChildVector.push_back(std::move(p));
72
73 // Hidden div. This is never referenced by marked content
74 // so it should not appear in the resulting PDF.
75 auto div = std::make_unique<PDFTag>();
76 div->fNodeId = 4;
77 div->fTypeString = "Div";
78 root->fChildVector.push_back(std::move(div));
79
80 // A bulleted list of two items.
81 auto l = std::make_unique<PDFTag>();
82 l->fNodeId = 5;
83 l->fTypeString = "L";
84
85 auto lm1 = std::make_unique<PDFTag>();
86 lm1->fNodeId = 6;
87 lm1->fTypeString = "Lbl";
88 l->fChildVector.push_back(std::move(lm1));
89
90 auto li1 = std::make_unique<PDFTag>();
91 li1->fNodeId = 7;
92 li1->fTypeString = "LI";
93 l->fChildVector.push_back(std::move(li1));
94
95 auto lm2 = std::make_unique<PDFTag>();
96 lm2->fNodeId = 8;
97 lm2->fTypeString = "Lbl";
98 l->fChildVector.push_back(std::move(lm2));
99 auto li2 = std::make_unique<PDFTag>();
100 li2->fNodeId = 9;
101 li2->fTypeString = "LI";
102 l->fChildVector.push_back(std::move(li2));
103
104 root->fChildVector.push_back(std::move(l));
105
106 // Paragraph spanning two pages.
107 auto p2 = std::make_unique<PDFTag>();
108 p2->fNodeId = 10;
109 p2->fTypeString = "P";
110 root->fChildVector.push_back(std::move(p2));
111
112 // Image with alt text.
113 auto img = std::make_unique<PDFTag>();
114 img->fNodeId = 11;
115 img->fTypeString = "Figure";
116 img->fAlt = "Red box";
117 root->fChildVector.push_back(std::move(img));
118
119 metadata.fStructureElementTreeRoot = root.get();
121 &outputStream, metadata);
122
124 paint.setColor(SK_ColorBLACK);
125
126 // First page.
127 SkCanvas* canvas =
128 document->beginPage(pageSize.width(),
129 pageSize.height());
130 SkPDF::SetNodeId(canvas, 2);
132 const char* message = "This is the title";
133 canvas->translate(72, 72);
134 canvas->drawString(message, 0, 0, font, paint);
135
136 SkPDF::SetNodeId(canvas, 3);
137 font.setSize(14);
138 message = "This is a simple paragraph.";
139 canvas->translate(0, 72);
140 canvas->drawString(message, 0, 0, font, paint);
141
142 SkPDF::SetNodeId(canvas, 6);
143 font.setSize(14);
144 message = "*";
145 canvas->translate(0, 72);
146 canvas->drawString(message, 0, 0, font, paint);
147
148 SkPDF::SetNodeId(canvas, 7);
149 message = "List item 1";
150 canvas->translate(36, 0);
151 canvas->drawString(message, 0, 0, font, paint);
152
153 SkPDF::SetNodeId(canvas, 8);
154 message = "*";
155 canvas->translate(-36, 36);
156 canvas->drawString(message, 0, 0, font, paint);
157
158 SkPDF::SetNodeId(canvas, 9);
159 message = "List item 2";
160 canvas->translate(36, 0);
161 canvas->drawString(message, 0, 0, font, paint);
162
163 SkPDF::SetNodeId(canvas, 10);
164 message = "This is a paragraph that starts on one page";
165 canvas->translate(-36, 6 * 72);
166 canvas->drawString(message, 0, 0, font, paint);
167
168 document->endPage();
169
170 // Second page.
171 canvas = document->beginPage(pageSize.width(),
172 pageSize.height());
173 SkPDF::SetNodeId(canvas, 10);
174 message = "and finishes on the second page.";
175 canvas->translate(72, 72);
176 canvas->drawString(message, 0, 0, font, paint);
177
178 // Test a tagged image with alt text.
179 SkPDF::SetNodeId(canvas, 11);
180 SkBitmap testBitmap;
181 testBitmap.allocN32Pixels(72, 72);
182 testBitmap.eraseColor(SK_ColorRED);
183 canvas->translate(72, 72);
184 canvas->drawImage(testBitmap.asImage(), 0, 0);
185
186 // This has a node ID but never shows up in the tag tree so it
187 // won't be tagged.
188 SkPDF::SetNodeId(canvas, 999);
189 message = "Page 2";
190 canvas->translate(468, -36);
191 canvas->drawString(message, 0, 0, font, paint);
192
193 document->endPage();
194
195 document->close();
196
197 outputStream.flush();
198}
199#endif
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER)
Definition Test.h:485
sk_sp< SkImage > asImage() const
Definition SkBitmap.cpp:645
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition SkBitmap.cpp:232
void eraseColor(SkColor4f) const
Definition SkBitmap.cpp:442
void translate(SkScalar dx, SkScalar dy)
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition SkCanvas.h:1803
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
virtual void flush()
Definition SkStream.cpp:77
const Paint & paint
Win32Message message
void GetDateTime(SkPDF::DateTime *)
SK_API sk_sp< SkDocument > MakeDocument(SkWStream *stream, const Metadata &metadata)
SK_API void SetNodeId(SkCanvas *dst, int nodeID)
sk_sp< SkTypeface > DefaultTypeface()
font
Font Metadata and Metrics.
enum SkPDF::Metadata::Outline fOutline
StructureElementNode * fStructureElementTreeRoot
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition SkSize.h:56
SkScalar width() const
Definition SkSize.h:76
SkScalar height() const
Definition SkSize.h:77