Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
pixbuf-ops.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Helpers for SPItem -> gdk_pixbuf related stuff
4 *
5 * Authors:
6 * John Cliff <simarilius@yahoo.com>
7 * Jon A. Cruz <jon@joncruz.org>
8 * Abhishek Sharma
9 *
10 * Copyright (C) 2008 John Cliff
11 *
12 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
13 */
14
15#include <2geom/transforms.h>
16
17#include "document.h"
18
19#include "display/cairo-utils.h"
21#include "display/drawing.h"
22#include "helper/pixbuf-ops.h"
23#include "object/sp-root.h"
24#include "util/scope_exit.h"
25#include "util/units.h"
26
37 Geom::Rect const &area,
38 double dpi,
39 std::vector<SPItem const *> items,
40 bool opaque,
41 uint32_t const *checkerboard_color,
42 double device_scale,
43 std::optional<Antialiasing> antialias)
44{
45 // Geometry
46 if (area.hasZeroArea()) {
47 return nullptr;
48 }
49
50 Geom::Point origin = area.min();
51 double scale_factor = Inkscape::Util::Quantity::convert(dpi, "px", "in");
52 Geom::Affine affine = Geom::Translate(-origin) * Geom::Scale (scale_factor, scale_factor);
53
54 int width = std::ceil(scale_factor * area.width());
55 int height = std::ceil(scale_factor * area.height());
56
57 // Document
58 document->ensureUpToDate();
59 unsigned dkey = SPItem::display_key_new(1);
60
61 // Drawing
62 Inkscape::Drawing drawing; // New drawing for offscreen rendering.
63 drawing.setRoot(document->getRoot()->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY));
64 auto invoke_hide_guard = scope_exit([&] { document->getRoot()->invoke_hide(dkey); });
65 drawing.root()->setTransform(affine);
66 drawing.setExact(); // Maximum quality for blurs.
67 drawing.setAntialiasingOverride(antialias);
68
69 // Hide all items we don't want, instead of showing only requested items,
70 // because that would not work if the shown item references something in defs.
71 if (!items.empty()) {
72 document->getRoot()->invoke_hide_except(dkey, items);
73 }
74
75 auto final_area = Geom::IntRect::from_xywh(0, 0, width, height);
76 drawing.update(final_area);
77
78 if (opaque) {
79 // Required by sp_asbitmap_render().
80 for (auto item : items) {
81 if (item->get_arenaitem(dkey)) {
82 item->get_arenaitem(dkey)->setOpacity(1.0);
83 }
84 }
85 }
86
87 // Rendering
88 cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
89
90 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
91 long long size = (long long)height * (long long)cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
92 g_warning("sp_generate_internal_bitmap: not enough memory to create pixel buffer. Need %lld.", size);
93 cairo_surface_destroy(surface);
94 return nullptr;
95 }
96
98
99 if (checkerboard_color) {
100 auto pattern = ink_cairo_pattern_create_checkerboard(*checkerboard_color);
101 dc.save();
102 dc.transform(Geom::Scale(device_scale));
103 dc.setOperator(CAIRO_OPERATOR_SOURCE);
104 dc.setSource(pattern);
105 dc.paint();
106 dc.restore();
107 cairo_pattern_destroy(pattern);
108 }
109
110 // render items
111 drawing.render(dc, final_area, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
112
113 if (device_scale != 1.0) {
114 cairo_surface_set_device_scale(surface, device_scale, device_scale);
115 }
116
117 return new Inkscape::Pixbuf(surface);
118}
119
120/*
121 Local Variables:
122 mode:c++
123 c-file-style:"stroustrup"
124 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
125 indent-tabs-mode:nil
126 fill-column:99
127 End:
128*/
129// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Point origin
Definition aa.cpp:227
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
3x3 matrix representing an affine transformation.
Definition affine.h:70
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 that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
bool hasZeroArea(Coord eps=EPSILON) const
Check whether the rectangle has zero area up to specified tolerance.
Definition rect.h:113
Scaling from the origin.
Definition transforms.h:150
Translation by a vector.
Definition transforms.h:115
Minimal wrapper over Cairo.
void setSource(cairo_pattern_t *source)
void transform(Geom::Affine const &trans)
void paint(double alpha=1.0)
void setOperator(cairo_operator_t op)
void setOpacity(float opacity)
void setTransform(Geom::Affine const &trans)
void setRoot(DrawingItem *root)
Definition drawing.cpp:64
DrawingItem * root()
Definition drawing.h:46
void update(Geom::IntRect const &area=Geom::IntRect::infinite(), Geom::Affine const &affine=Geom::identity(), unsigned flags=DrawingItem::STATE_ALL, unsigned reset=0)
Definition drawing.cpp:228
void render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags=0) const
Definition drawing.cpp:239
void setAntialiasingOverride(std::optional< Antialiasing > antialiasing_override)
Definition drawing.cpp:219
Class to hold image data for raster images.
Definition cairo-utils.h:31
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:588
Typed SVG document implementation.
Definition document.h:101
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:200
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
Inkscape::DrawingItem * invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
Definition sp-item.cpp:1285
Inkscape::DrawingItem * get_arenaitem(unsigned key) const
Return the arenaitem corresponding to the given item in the display with the given key.
Definition sp-item.cpp:1864
static unsigned int display_key_new(unsigned numkeys)
Allocates unique integer keys.
Definition sp-item.cpp:1262
void invoke_hide_except(unsigned key, const std::vector< SPItem const * > &to_keep)
Invoke hide on all non-group items, except for the list of items to keep.
Definition sp-item.cpp:1374
Geom::IntPoint size
Cairo drawing context with Inkscape extensions.
struct _cairo_surface cairo_surface_t
SVG drawing for display.
SPItem * item
Inkscape::Pixbuf * sp_generate_internal_bitmap(SPDocument *document, Geom::Rect const &area, double dpi, std::vector< SPItem const * > items, bool opaque, uint32_t const *checkerboard_color, double device_scale, std::optional< Antialiasing > antialias)
Generates a bitmap from given items.
GList * items
Run code on scope exit.
SPRoot: SVG <svg> implementation.
double height
double width
Affine transformation classes.