Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
preview.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/* Authors:
7 * Anshudhar Kumar Singh <anshudhar2001@gmail.com>
8 * Martin Owens <doctormo@gmail.com>
9 *
10 * Copyright (C) 2021 Anshudhar Kumar Singh
11 * 2021 Martin Owens
12 *
13 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
14 */
15
16#include "preview.h"
17
18#include "display/cairo-utils.h"
20
21namespace Inkscape {
22namespace UI {
23namespace Preview {
24
25Cairo::RefPtr<Cairo::ImageSurface>
26render_preview(SPDocument *doc, std::shared_ptr<Inkscape::Drawing> drawing, uint32_t bg,
27 Inkscape::DrawingItem *item, unsigned width_in, unsigned height_in, Geom::Rect const &dboxIn)
28{
29 if (!drawing->root())
30 return {};
31
32 // Calculate a scaling factor for the requested bounding box.
33 double sf = 1.0;
34 Geom::IntRect ibox = dboxIn.roundOutwards();
35 if (ibox.width() != width_in || ibox.height() != height_in) {
36 // Adjust by one pixel to fit in anti-aliasing pixels
37 sf = std::min((double)(width_in - 1) / dboxIn.width(),
38 (double)(height_in - 1) / dboxIn.height());
39 auto scaled_box = dboxIn * Geom::Scale(sf);
40 ibox = scaled_box.roundOutwards();
41 }
42
43 auto pdim = Geom::IntPoint(width_in, height_in);
44 // The unsigned width/height can wrap around when negative.
45 int dx = ((int)width_in - ibox.width()) / 2;
46 int dy = ((int)height_in - ibox.height()) / 2;
47 auto area = Geom::IntRect::from_xywh(ibox.min() - Geom::IntPoint(dx, dy), pdim);
48
49 /* Actual renderable area */
50 auto const ua = Geom::intersect(ibox, area);
51 if (!ua) {
52 return {};
53 }
54 auto surface = Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32, ua->width(), ua->height());
55
56 auto on_error = [&] (char const *err) {
57 std::cerr << "render_preview: " << err << std::endl;
58 surface = Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32, ua->width(), ua->height());
59 };
60
61 try {
62 {
63 auto cr = Cairo::Context::create(surface);
64 cr->rectangle(0, 0, ua->width(), ua->height());
65
66 // We always use checkerboard to indicate transparency.
67 if (SP_RGBA32_A_F(bg) < 1.0) {
68 auto pattern = ink_cairo_pattern_create_checkerboard(bg, false);
69 auto background = Cairo::RefPtr<Cairo::Pattern>(new Cairo::Pattern(pattern, true));
70 cr->set_source(background);
71 cr->fill();
72 }
73
74 // We always draw the background on top to indicate partial backgrounds.
75 cr->set_source_rgba(SP_RGBA32_R_F(bg), SP_RGBA32_G_F(bg), SP_RGBA32_B_F(bg), SP_RGBA32_A_F(bg));
76 cr->fill();
77 }
78
79 // Resize the contents to the available space with a scale factor.
80 drawing->root()->setTransform(Geom::Scale(sf));
81 drawing->update();
82
83 auto dc = Inkscape::DrawingContext(surface->cobj(), ua->min());
84 if (item) {
85 // Render just one item
86 item->render(dc, *ua);
87 } else {
88 // Render drawing.
89 drawing->render(dc, *ua);
90 }
91
92 surface->flush();
93 } catch (std::bad_alloc const &e) {
94 on_error(e.what());
95 } catch (Cairo::logic_error const &e) {
96 on_error(e.what());
97 }
98
99 return surface;
100}
101
102} // namespace Preview
103} // namespace UI
104} // namespace Inkscape
cairo_pattern_t * ink_cairo_pattern_create_checkerboard(guint32 rgba, bool use_alpha)
Cairo integration helpers.
Cairo::RefPtr< Cairo::ImageSurface > surface
Definition canvas.cpp:137
Axis aligned, non-empty, generic rectangle.
static CRect from_xywh(C x, C y, C w, C h)
Create rectangle from origin and dimensions.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
Two-dimensional point with integer coordinates.
Definition int-point.h:57
Axis aligned, non-empty rectangle.
Definition rect.h:92
IntRect roundOutwards() const
Return the smallest integer rectangle which contains this one.
Definition rect.h:141
Scaling from the origin.
Definition transforms.h:150
Minimal wrapper over Cairo.
SVG drawing item for display.
Typed SVG document implementation.
Definition document.h:101
constexpr double SP_RGBA32_G_F(uint32_t v)
Definition utils.h:47
constexpr double SP_RGBA32_R_F(uint32_t v)
Definition utils.h:43
constexpr double SP_RGBA32_A_F(uint32_t v)
Definition utils.h:55
constexpr double SP_RGBA32_B_F(uint32_t v)
Definition utils.h:51
Cairo drawing context with Inkscape extensions.
SPItem * item
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
Definition conicsec.cpp:361
Cairo::RefPtr< Cairo::ImageSurface > render_preview(SPDocument *doc, std::shared_ptr< Inkscape::Drawing > drawing, uint32_t bg, Inkscape::DrawingItem *item, unsigned width_in, unsigned height_in, Geom::Rect const &dboxIn)
Launch a background task to render a drawing to a surface.
Definition preview.cpp:26
Helper class to stream background task notifications as a series of messages.
Utility functions for previewing icon representation.