Fixes broken export to PDF with links.
[inkscape.git] / testfiles / src / drawing-pattern-test.cpp
blob95a81ef8c1f716c69a00323a51379bcfdf0a9d8a
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /**
3 * @file
4 * Test drawing_pattern_test
5 */
6 /*
7 * Authors:
8 * PBS <pbs3141@gmail.com>
10 * Copyright (C) 2022 Authors
12 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
14 #include <gtest/gtest.h>
16 #include <cairomm/surface.h>
17 #include <2geom/int-rect.h>
18 #include <2geom/int-point.h>
20 #include "inkscape.h"
21 #include "document.h"
22 #include "object/sp-root.h"
23 #include "display/drawing.h"
24 #include "display/drawing-surface.h"
25 #include "display/drawing-context.h"
27 TEST(DrawingPatternTest, fragments)
29 if (!Inkscape::Application::exists()) {
30 Inkscape::Application::create(false);
33 auto doc = std::unique_ptr<SPDocument>(SPDocument::createNewDoc(INKSCAPE_TESTS_DIR "/rendering_tests/drawing-pattern-test.svg", false));
34 ASSERT_TRUE((bool)doc);
35 ASSERT_TRUE((bool)doc->getRoot());
37 doc->ensureUpToDate();
39 class Display
41 public:
42 Display(SPDocument *doc) {
43 root = doc->getRoot();
44 dkey = SPItem::display_key_new(1);
45 rootitem = root->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY);
46 drawing.setRoot(rootitem);
47 drawing.update();
50 ~Display()
52 root->invoke_hide(dkey);
55 auto draw(Geom::IntRect const &rect)
57 auto cs = Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32, rect.width(), rect.height());
58 auto ds = Inkscape::DrawingSurface(cs->cobj(), rect.min());
59 auto dc = Inkscape::DrawingContext(ds);
60 drawing.render(dc, rect);
61 return cs;
64 private:
65 Inkscape::Drawing drawing;
66 SPRoot *root;
67 Inkscape::DrawingItem *rootitem;
68 unsigned dkey;
71 auto const tile = Geom::IntPoint(30, 30);
72 auto const area = Geom::IntRect::from_xywh(0, 0, 100, 100);
74 auto const reference = Display(doc.get()).draw(area);
76 uint32_t state = 0;
77 auto rand = [&] {
78 state = (state * 1103515245) + 12345;
79 return state;
81 rand();
83 auto randrect = [&] {
84 int w = rand() % tile.x() / 3 + 1;
85 int h = rand() % tile.y() / 3 + 1;
86 int x = rand() % (area.width() - w + 1);
87 int y = rand() % (area.height() - h + 1);
88 return Geom::IntRect::from_xywh(x, y, w, h);
91 int maxdiff = 0;
92 auto compare = [&] (Cairo::RefPtr<Cairo::ImageSurface> const &part, Geom::IntPoint const &off) {
93 for (int y = 0; y < part->get_height(); y++) {
94 auto p = reference->get_data() + (off.y() + y) * reference->get_stride() + off.x() * 4;
95 auto q = part->get_data() + y * part->get_stride();
96 for (int x = 0; x < part->get_width(); x++) {
97 for (int c = 0; c < 4; c++) {
98 auto diff = std::abs((int)p[c] - (int)q[c]);
99 maxdiff = std::max(maxdiff, diff);
101 p += 4;
102 q += 4;
107 for (int j = 0; j < 5; j++) {
108 auto d = Display(doc.get());
109 for (int i = 0; i < 20; i++) {
110 auto const rect = randrect();
111 auto const part = d.draw(rect);
112 compare(part, rect.min());
116 ASSERT_LE(maxdiff, 10);