Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
page-size-preview.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
7/*
8 * Authors:
9 * Mike Kowalski
10 *
11 * Copyright (C) 2021 Authors
12 *
13 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
14 */
15
16#include "page-size-preview.h"
17#include "display/cairo-utils.h"
18#include <2geom/rect.h>
19
20namespace Inkscape {
21namespace UI {
22namespace Widget {
23
25 set_visible(true);
26 set_draw_func(sigc::mem_fun(*this, &PageSizePreview::draw_func));
27}
28
29void rounded_rectangle(const Cairo::RefPtr<Cairo::Context>& cr, double x, double y, double w, double h, double r) {
30 cr->begin_new_sub_path();
31 cr->arc(x + r, y + r, r, M_PI, 3 * M_PI / 2);
32 cr->arc(x + w - r, y + r, r, 3 * M_PI / 2, 2 * M_PI);
33 cr->arc(x + w - r, y + h - r, r, 0, M_PI / 2);
34 cr->arc(x + r, y + h - r, r, M_PI / 2, M_PI);
35 cr->close_path();
36}
37
38void set_source_rgba(const Cairo::RefPtr<Cairo::Context>& ctx, unsigned int rgba) {
39 ctx->set_source_rgba(SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba), SP_RGBA32_A_F(rgba));
40}
41
42void PageSizePreview::draw_func(Cairo::RefPtr<Cairo::Context> const &ctx, int width, int height) {
43 // too small to fit anything?
44 if (width <= 2 || height <= 2) return;
45
46 double x = 0;//alloc.get_x();
47 double y = 0;//alloc.get_y();
48
50 // auto device_scale = get_scale_factor();
51 Cairo::RefPtr<Cairo::Pattern> pattern(new Cairo::Pattern(ink_cairo_pattern_create_checkerboard(_desk_color)));
52 ctx->save();
53 ctx->set_operator(Cairo::Context::Operator::SOURCE);
54 ctx->set_source(pattern);
55 rounded_rectangle(ctx, x, y, width, height, 2.0);
56 ctx->fill();
57 ctx->restore();
58 }
59 else {
60 rounded_rectangle(ctx, x, y, width, height, 2.0);
62 ctx->fill();
63 }
64
65 // use lesser dimension to prevent page from changing size when
66 // switching from portrait to landscape or vice versa
67 auto size = std::round(std::min(width, height) * 0.90); // 90% to leave margins
68 double w, h;
69 if (_width > _height) {
70 w = size;
71 h = std::round(size * _height / _width);
72 }
73 else {
74 h = size;
75 w = std::round(size * _width / _height);
76 }
77 if (w < 2) w = 2;
78 if (h < 2) h = 2;
79
80 // center page
81 double ox = std::round(x + (width - w) / 2);
82 double oy = std::round(y + (height - h) / 2);
83 Geom::Rect rect(ox, oy, ox + w, oy + h);
84
85 ctx->rectangle(rect.left(), rect.top(), rect.width(), rect.height());
86
88 Cairo::RefPtr<Cairo::Pattern> pattern(new Cairo::Pattern(ink_cairo_pattern_create_checkerboard(_page_color)));
89 ctx->save();
90 ctx->set_operator(Cairo::Context::Operator::SOURCE);
91 ctx->set_source(pattern);
92 ctx->rectangle(rect.left(), rect.top(), rect.width(), rect.height());
93 ctx->fill();
94 ctx->restore();
95 }
96 else {
97 ctx->rectangle(rect.left(), rect.top(), rect.width(), rect.height());
98 set_source_rgba(ctx, _page_color | 0xff);
99 ctx->fill();
100 }
101
102 // draw cross
103 /*
104 {
105 double gradient_size = 4;
106 double cx = std::round(x + (width - gradient_size) / 2);
107 double cy = std::round(y + (height - gradient_size) / 2);
108 auto horz = Cairo::LinearGradient::create(x, cy, x, cy + gradient_size);
109 auto vert = Cairo::LinearGradient::create(cx, y, cx + gradient_size, y);
110
111 horz->add_color_stop_rgba(0.0, 0, 0, 0, 0.0);
112 horz->add_color_stop_rgba(0.5, 0, 0, 0, 0.2);
113 horz->add_color_stop_rgba(0.5, 1, 1, 1, 0.8);
114 horz->add_color_stop_rgba(1.0, 1, 1, 1, 0.0);
115
116 vert->add_color_stop_rgba(0.0, 0, 0, 0, 0.0);
117 vert->add_color_stop_rgba(0.5, 0, 0, 0, 0.2);
118 vert->add_color_stop_rgba(0.5, 1, 1, 1, 0.8);
119 vert->add_color_stop_rgba(1.0, 1, 1, 1, 0.0);
120
121 ctx->rectangle(x, cy, width, gradient_size);
122 ctx->set_source(horz);
123 ctx->fill();
124
125 ctx->rectangle(cx, y, gradient_size, height);
126 ctx->set_source(vert);
127 ctx->fill();
128 }
129
130 ctx->rectangle(rect.left(), rect.top(), rect.width(), rect.height());
131 set_source_rgba(ctx, _page_color);
132 ctx->fill();
133*/
134 if (_draw_border) {
135 // stoke; not pixel aligned, just like page on canvas
136 ctx->rectangle(rect.left(), rect.top(), rect.width(), rect.height());
138 ctx->set_line_width(1);
139 ctx->stroke();
140
141 if (_draw_shadow) {
142 const auto a = (exp(-3 * SP_RGBA32_A_F(_border_color)) - 1) / (exp(-3) - 1);
143 ink_cairo_draw_drop_shadow(ctx, rect, 12, _border_color, a);
144 }
145 }
146}
147
150 queue_draw();
151}
152
153void PageSizePreview::set_desk_color(unsigned int rgba) {
154 _desk_color = rgba | 0xff; // desk always opaque
155 queue_draw();
156}
157void PageSizePreview::set_page_color(unsigned int rgba) {
158 _page_color = rgba;
159 queue_draw();
160}
161void PageSizePreview::set_border_color(unsigned int rgba) {
162 _border_color = rgba;
163 queue_draw();
164}
165
167 _draw_shadow = shadow;
168 queue_draw();
169}
170
172 _draw_checkerboard = checkerboard;
173 queue_draw();
174}
175
177 _width = width;
178 _height = height;
179 queue_draw();
180}
181
182} } } // namespace Inkscape/Widget/UI
void ink_cairo_draw_drop_shadow(const Cairo::RefPtr< Cairo::Context > &ctx, const Geom::Rect &rect, double size, guint32 color, double color_alpha)
Draw drop shadow around the 'rect' with given 'size' and 'color'; shadow extends to the right and bot...
cairo_pattern_t * ink_cairo_pattern_create_checkerboard(guint32 rgba, bool use_alpha)
Cairo integration helpers.
C top() const
Return top coordinate of the rectangle (+Y is downwards).
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
Axis aligned, non-empty rectangle.
Definition rect.h:92
void draw_func(Cairo::RefPtr< Cairo::Context > const &cr, int width, int height)
void set_page_size(double width, double height)
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
const double w
Definition conic-4.cpp:19
void rounded_rectangle(const Cairo::RefPtr< Cairo::Context > &cr, double x, double y, double w, double h, double r)
static constexpr int height
void set_source_rgba(const Cairo::RefPtr< Cairo::Context > &ctx, unsigned int rgba)
Helper class to stream background task notifications as a series of messages.
Axis-aligned rectangle.
double border
double width