1 /*
2 * Copyright 2011 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
8 #include "include/core/SkAnnotation.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkDocument.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkStream.h"
19 #include "include/core/SkTypes.h"
20 #include "include/docs/SkPDFDocument.h"
21 #include "include/docs/SkPDFJpegHelpers.h"
22 #include "tests/Test.h"
23
24 #include <cstddef>
25 #include <cstring>
26
27 /** Returns true if data (may contain null characters) contains needle (null
28 * terminated). */
ContainsString(const char * data,size_t dataSize,const char * needle)29 static bool ContainsString(const char* data, size_t dataSize, const char* needle) {
30 size_t nSize = strlen(needle);
31 for (size_t i = 0; i < dataSize - nSize; i++) {
32 if (strncmp(&data[i], needle, nSize) == 0) {
33 return true;
34 }
35 }
36 return false;
37 }
38
DEF_TEST(Annotation_NoDraw,reporter)39 DEF_TEST(Annotation_NoDraw, reporter) {
40 SkBitmap bm;
41 bm.allocN32Pixels(10, 10);
42 bm.eraseColor(SK_ColorTRANSPARENT);
43
44 SkCanvas canvas(bm);
45 SkRect r = SkRect::MakeWH(SkIntToScalar(10), SkIntToScalar(10));
46
47 sk_sp<SkData> data(SkData::MakeWithCString("http://www.gooogle.com"));
48
49 REPORTER_ASSERT(reporter, 0 == *bm.getAddr32(0, 0));
50 SkAnnotateRectWithURL(&canvas, r, data.get());
51 REPORTER_ASSERT(reporter, 0 == *bm.getAddr32(0, 0));
52 }
53
DEF_TEST(Annotation_PdfLink,reporter)54 DEF_TEST(Annotation_PdfLink, reporter) {
55 REQUIRE_PDF_DOCUMENT(Annotation_PdfLink, reporter);
56 SkDynamicMemoryWStream outStream;
57 auto doc = SkPDF::MakeDocument(&outStream, SkPDF::JPEG::MetadataWithCallbacks());
58 SkCanvas* canvas = doc->beginPage(612.0f, 792.0f);
59 REPORTER_ASSERT(reporter, canvas);
60
61 SkRect r = SkRect::MakeXYWH(SkIntToScalar(72), SkIntToScalar(72),
62 SkIntToScalar(288), SkIntToScalar(72));
63 sk_sp<SkData> data(SkData::MakeWithCString("http://www.gooogle.com"));
64 SkAnnotateRectWithURL(canvas, r, data.get());
65
66 doc->close();
67 sk_sp<SkData> out = outStream.detachAsData();
68 const char* rawOutput = (const char*)out->data();
69
70 REPORTER_ASSERT(reporter, ContainsString(rawOutput, out->size(), "/Annots "));
71 }
72
DEF_TEST(Annotation_PdfDefineNamedDestination,reporter)73 DEF_TEST(Annotation_PdfDefineNamedDestination, reporter) {
74 REQUIRE_PDF_DOCUMENT(Annotation_PdfNamedDestination, reporter);
75 SkDynamicMemoryWStream outStream;
76 auto doc = SkPDF::MakeDocument(&outStream, SkPDF::JPEG::MetadataWithCallbacks());
77 SkCanvas* canvas = doc->beginPage(612.0f, 792.0f);
78 REPORTER_ASSERT(reporter, canvas);
79
80 SkPoint p = SkPoint::Make(SkIntToScalar(72), SkIntToScalar(72));
81 sk_sp<SkData> data(SkData::MakeWithCString("example"));
82 SkAnnotateNamedDestination(canvas, p, data.get());
83
84 doc->close();
85 sk_sp<SkData> out = outStream.detachAsData();
86 const char* rawOutput = (const char*)out->data();
87
88 REPORTER_ASSERT(reporter,
89 ContainsString(rawOutput, out->size(), "/example "));
90 }
91
92 #if defined(SK_XML)
93 #include "include/svg/SkSVGCanvas.h"
94
DEF_TEST(Annotation_SvgLink,reporter)95 DEF_TEST(Annotation_SvgLink, reporter) {
96 SkDynamicMemoryWStream outStream;
97 SkRect bounds = SkRect::MakeIWH(400, 400);
98 std::unique_ptr<SkCanvas> canvas = SkSVGCanvas::Make(bounds, &outStream);
99
100 SkRect r = SkRect::MakeXYWH(SkIntToScalar(72), SkIntToScalar(72), SkIntToScalar(288),
101 SkIntToScalar(72));
102 sk_sp<SkData> data(SkData::MakeWithCString("http://www.gooogle.com"));
103 SkAnnotateRectWithURL(canvas.get(), r, data.get());
104
105 sk_sp<SkData> out = outStream.detachAsData();
106 const char* rawOutput = (const char*)out->data();
107
108 REPORTER_ASSERT(reporter,
109 ContainsString(rawOutput, out->size(), "a xlink:href=\"http://www.gooogle.com\""));
110 }
111
DEF_TEST(Annotation_SvgLinkNamedDestination,reporter)112 DEF_TEST(Annotation_SvgLinkNamedDestination, reporter) {
113 SkDynamicMemoryWStream outStream;
114 SkRect bounds = SkRect::MakeIWH(400, 400);
115 std::unique_ptr<SkCanvas> canvas = SkSVGCanvas::Make(bounds, &outStream);
116
117 SkRect r = SkRect::MakeXYWH(SkIntToScalar(72), SkIntToScalar(72), SkIntToScalar(288),
118 SkIntToScalar(72));
119 sk_sp<SkData> data(SkData::MakeWithCString("http://www.gooogle.com/#NamedDestination"));
120 SkAnnotateLinkToDestination(canvas.get(), r, data.get());
121
122 sk_sp<SkData> out = outStream.detachAsData();
123 const char* rawOutput = (const char*)out->data();
124
125 REPORTER_ASSERT(reporter,
126 ContainsString(rawOutput, out->size(),
127 "a xlink:href=\"http://www.gooogle.com/#NamedDestination\""));
128 }
129 #endif
130