skia2/tests/PDFTaggedLinkTest.cpp
Dominic Mazzoni c227f4a826 Add support for tagging link annotations in PDFs.
Properly tagging links in PDFs just required a small change: at the time
an annotation is drawn, we need to keep track of the bounding rect, the
url and/or named destination, and now additionally the node ID. Instead
of keeping track of separate maps of rects/urls and rects/dests, this
patch combines them into a vector of SkPDFLinks.

Then, at the time the annotation is written to the file, an object
reference to that annotation can be saved and passed to the document
structure tree, where it can be included as an additional child of
the node with that node ID.

That allows for properly tagging the link and optionally giving it alt
text (like for an image link).

Bug: chromium:1039816
Change-Id: I97e47d3c70949020c3e0a69b8c9fc743748f3a7b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/277426
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: Ben Wagner <bungeman@google.com>
2020-03-24 15:52:55 +00:00

79 lines
2.3 KiB
C++

/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tests/Test.h"
#ifdef SK_SUPPORT_PDF
#include "include/core/SkAnnotation.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkStream.h"
#include "include/docs/SkPDFDocument.h"
using PDFTag = SkPDF::StructureElementNode;
// Test building a tagged PDF with links.
// Add this to args.gn to output the PDF to a file:
// extra_cflags = [ "-DSK_PDF_TEST_TAGS_OUTPUT_PATH=\"/tmp/links.pdf\"" ]
DEF_TEST(SkPDF_tagged_links, r) {
REQUIRE_PDF_DOCUMENT(SkPDF_tagged_links, r);
#ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
#else
SkDynamicMemoryWStream outputStream;
#endif
SkSize pageSize = SkSize::Make(612, 792); // U.S. Letter
SkPDF::Metadata metadata;
metadata.fTitle = "Example Tagged PDF With Links";
metadata.fCreator = "Skia";
SkTime::DateTime now;
SkTime::GetDateTime(&now);
metadata.fCreation = now;
metadata.fModified = now;
// The document tag.
auto root = std::make_unique<PDFTag>();
root->fNodeId = 1;
root->fTypeString = "Document";
root->fLang = "en-US";
// A link.
auto l1 = std::make_unique<PDFTag>();
l1->fNodeId = 2;
l1->fTypeString = "Link";
root->fChildVector.push_back(std::move(l1));
metadata.fStructureElementTreeRoot = root.get();
sk_sp<SkDocument> document = SkPDF::MakeDocument(
&outputStream, metadata);
SkPaint paint;
paint.setColor(SK_ColorBLUE);
SkCanvas* canvas =
document->beginPage(pageSize.width(),
pageSize.height());
SkFont font(nullptr, 20);
// The node ID should cover both the text and the annotation.
SkPDF::SetNodeId(canvas, 2);
canvas->drawString("Click to visit Google.com", 72, 72, font, paint);
SkRect linkRect = SkRect::MakeXYWH(
SkIntToScalar(72), SkIntToScalar(54),
SkIntToScalar(218), SkIntToScalar(24));
sk_sp<SkData> url(SkData::MakeWithCString("http://www.google.com"));
SkAnnotateRectWithURL(canvas, linkRect, url.get());
document->endPage();
document->close();
outputStream.flush();
}
#endif