Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
svg-box.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Authors:
4 * Martin Owens <doctormo@geek-2.com>
5 *
6 * Copyright (C) 2022 Martin Owens
7 *
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10
11#include <cstring>
12#include <string>
13#include <iostream>
14
15#include <glib.h>
16#include <glibmm/regex.h>
17
18#include "svg/svg-box.h"
19#include "util/units.h"
20
21// Match a side to it's fallback index,
22// top->bottom, top->right, right->left
23#define FALLBACK(i) ((i - 2 >= 0) ? (i - 2) : 0)
24
31
35bool SVGBox::read(const std::string &value, const Geom::Scale &doc_scale)
36{
37 return fromString(value, "", doc_scale);
38}
39
43void SVGBox::update(double em, double ex, double width, double height)
44{
45 _value[0].update(em, ex, height);
46 _value[1].update(em, ex, width);
47 _value[2].update(em, ex, height);
48 _value[3].update(em, ex, width);
49}
50
54std::string SVGBox::write() const
55{
56 return toString("", Geom::Scale(1));
57}
58
62std::string SVGBox::toString(const std::string &unit, const Geom::Scale &doc_scale, std::optional<unsigned int> precision, bool add_unit) const
63{
64 std::string ret = "";
65 bool write = false;
66 for (int i = 3; i >= 0; i--) {
67 SVGLength val = _value[i];
68 SVGLength fallback = _value[FALLBACK(i)];
69 if (i == BOX_TOP || (val != fallback) || write) {
70 if (unit.size()) {
71 auto axis_scale = doc_scale[get_scale_axis((BoxSide)i)];
72 ret = std::string(val.toString(unit, axis_scale, precision, add_unit)) + " " + ret;
73 } else {
74 ret = std::string(val.write()) + " " + ret;
75 }
76 write = true;
77 }
78 }
79 ret.pop_back();
80 return ret;
81}
82
86bool SVGBox::fromString(const std::string &value, const std::string &unit, const Geom::Scale &doc_scale)
87{
88 if (!value.size()) return false;
89
90 // A. Split by spaces.
91 std::vector<Glib::ustring> elements = Glib::Regex::split_simple("\\s*[,\\s]\\s*", value.c_str());
92
93 // Take item zero
94 for (int i = 0; i < 4; i++) {
95 if ((i == BOX_TOP || (int)elements.size() >= i+1) && elements[i].size() > 0) {
96 if (!fromString((BoxSide)i, elements[i], unit, doc_scale)) {
97 return false; // One position failed.
98 }
99 } else {
100 _value[i] = _value[FALLBACK(i)];
101 }
102 }
103
104 _is_set = true;
105 return true;
106}
107
116bool SVGBox::fromString(BoxSide side, const std::string &value, const std::string &unit, const Geom::Scale &doc_scale)
117{
118 double axis_scale = doc_scale[get_scale_axis(side)];
119 return _value[side].fromString(value, unit, axis_scale);
120}
121
125bool SVGBox::isZero() const
126{
127 return _value[0] == 0.0
128 && _value[1] == 0.0
129 && _value[2] == 0.0
130 && _value[3] == 0.0;
131}
132
136void SVGBox::set(double top, double right, double bottom, double left) {
137 set(BOX_TOP, top);
140 set(BOX_LEFT, left);
141}
142
148void SVGBox::set(BoxSide side, double px, bool confine) {
149 // Unit gets destroyed here delibrately. Units are not ok in the svg.
150 SVGLength original = _value[side];
151 for (int i = 0; i < 4; i++) {
152 if (i == (int)side || (confine && _value[i] == original)) {
153 _value[i].set(SVGLength::PX, px, px);
154 }
155 }
156 _is_set = true;
157}
158
160 _is_set = false;
161}
162
163void SVGBox::readOrUnset(gchar const *value, const Geom::Scale &doc_scale) {
164 if (!value || !read(value, doc_scale)) {
165 unset();
166 }
167}
168
169/*
170 Local Variables:
171 mode:c++
172 c-file-style:"stroustrup"
173 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
174 indent-tabs-mode:nil
175 fill-column:99
176 End:
177*/
178// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Scaling from the origin.
Definition transforms.h:150
SVGLength bottom() const
Definition svg-box.h:61
void set(BoxSide side, double value, bool confine=false)
Set the value of the side, retaining it's original unit.
Definition svg-box.cpp:148
void unset()
Definition svg-box.cpp:159
SVGLength left() const
Definition svg-box.h:62
SVGLength _value[4]
Definition svg-box.h:68
static Geom::Dim2 get_scale_axis(BoxSide side)
Definition svg-box.h:64
bool fromString(const std::string &value, const std::string &unit, const Geom::Scale &doc_scale)
Set the svg box from user input, with a default unit.
Definition svg-box.cpp:86
bool isZero() const
Returns true if the box is set, but all values are zero.
Definition svg-box.cpp:125
void readOrUnset(gchar const *str, const Geom::Scale &doc_scale)
Definition svg-box.cpp:163
std::string write() const
Write out the values into a compact form.
Definition svg-box.cpp:54
bool _is_set
Definition svg-box.h:66
void update(double em, double ex, double width, double height)
Update box with em, ex and percentage scaling.
Definition svg-box.cpp:43
SVGBox()
An svg box is a type of css/html type which contains up to 4 svg lengths.
Definition svg-box.cpp:29
bool read(const std::string &value, const Geom::Scale &doc_scale)
Read in the value, may be an array of four.
Definition svg-box.cpp:35
std::string toString(const std::string &unit, const Geom::Scale &doc_scale, std::optional< unsigned int > precision={}, bool add_unit=true) const
Write as specific unit for user display.
Definition svg-box.cpp:62
SVGLength top() const
Definition svg-box.h:59
SVGLength right() const
Definition svg-box.h:60
SVG length type.
Definition svg-length.h:22
std::string toString(const std::string &unit, double doc_scale, std::optional< unsigned int > precision={}, bool add_unit=true) const
Write out length in user unit, for the user to use.
void set(Unit u, float v)
std::string write() const
bool fromString(const std::string &input, const std::string &unit, std::optional< double > scale={})
Read from user input, any non-unitised value is converted internally.
void update(double em, double ex, double scale)
std::string original
BoxSide
Definition svg-box.h:19
@ BOX_BOTTOM
Definition svg-box.h:22
@ BOX_LEFT
Definition svg-box.h:23
@ BOX_TOP
Definition svg-box.h:20
@ BOX_RIGHT
Definition svg-box.h:21
double height
double width