1 /* BStyles.cpp
2 * Copyright (C) 2018 Sven Jähnichen
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "BStyles.hpp"
19
20 namespace BStyles
21 {
22
23 /*****************************************************************************
24 * Class BStyles::Line
25 *****************************************************************************/
26
Line()27 Line::Line () : Line (BColors::invisible, 0.0) {}
Line(const BColors::Color & color,const double width)28 Line::Line (const BColors::Color& color, const double width) : lineColor (color), lineWidth (width) {}
setColor(const BColors::Color & color)29 void Line::setColor (const BColors::Color& color) {lineColor = color;}
getColor()30 BColors::Color* Line::getColor () {return &lineColor;}
setWidth(const double width)31 void Line::setWidth (const double width) {lineWidth = width;}
getWidth() const32 double Line::getWidth () const {return lineWidth;}
33
34 /*
35 * End of class BWidgets::Line
36 *****************************************************************************/
37
38
39 /*****************************************************************************
40 * Class BStyles::Border
41 *****************************************************************************/
42
Border()43 Border::Border () : Border (noLine, 0.0, 0.0, 0.0) {}
Border(const Line & line)44 Border::Border (const Line& line) : Border (line, 0.0, 0.0, 0.0) {}
Border(const Line & line,const double margin,const double padding)45 Border::Border (const Line& line, const double margin, const double padding) : Border (line, margin, padding, 0.0) {}
Border(const Line & line,const double margin,const double padding,const double radius)46 Border::Border (const Line& line, const double margin, const double padding, const double radius) :
47 borderLine (line), borderMargin (margin), borderPadding (padding), borderRadius (radius) {}
48
setLine(const Line & line)49 void Border::setLine (const Line& line) {borderLine = line;}
getLine()50 Line* Border::getLine () {return &borderLine;}
setMargin(const double margin)51 void Border::setMargin (const double margin) {borderMargin = margin;}
getMargin() const52 double Border::getMargin () const {return borderMargin;}
setPadding(const double padding)53 void Border::setPadding (const double padding) {borderPadding = padding;}
getPadding() const54 double Border::getPadding () const {return borderPadding;}
setRadius(const double radius)55 void Border::setRadius (const double radius) {borderRadius = radius;}
getRadius() const56 double Border::getRadius () const {return borderRadius;}
57
58 /*
59 * End of class BWidgets::Border
60 *****************************************************************************/
61
62
63 /*****************************************************************************
64 * Class BStyles::Fill
65 *****************************************************************************/
66
Fill()67 Fill::Fill () : fillColor (BColors::invisible), fillSurface (nullptr) {}
Fill(const BColors::Color & color)68 Fill::Fill (const BColors::Color& color) : fillColor (color), fillSurface (nullptr) {}
Fill(const std::string & filename)69 Fill::Fill (const std::string& filename) : fillColor (BColors::invisible), fillSurface (nullptr)
70 {
71 loadFillFromFile (filename);
72 }
73
Fill(const Fill & that)74 Fill::Fill (const Fill& that)
75 {
76 fillColor = that.fillColor;
77 if (that.fillSurface) fillSurface = cairo_image_surface_clone_from_image_surface (that.fillSurface);
78 else fillSurface = nullptr;
79 }
80
operator =(const Fill & that)81 Fill& Fill::operator= (const Fill& that)
82 {
83 if (this != &that)
84 {
85 fillColor = that.fillColor;
86 if (that.fillSurface) fillSurface = cairo_image_surface_clone_from_image_surface (that.fillSurface);
87 else fillSurface = nullptr;
88 }
89
90 return *this;
91 }
92
~Fill()93 Fill::~Fill ()
94 {
95 if (fillSurface && (cairo_surface_status (fillSurface) == CAIRO_STATUS_SUCCESS)) cairo_surface_destroy (fillSurface);
96 }
97
setColor(const BColors::Color & color)98 void Fill::setColor (const BColors::Color& color) {fillColor = color;}
99
getColor()100 BColors::Color* Fill::getColor () {return &fillColor;}
101
loadFillFromFile(const std::string & filename)102 void Fill::loadFillFromFile (const std::string& filename)
103 {
104 if (fillSurface) cairo_surface_destroy (fillSurface);
105 fillSurface = cairo_image_surface_create_from_png (filename.c_str());
106 }
107
loadFillFromCairoSurface(cairo_surface_t * surface)108 void Fill::loadFillFromCairoSurface (cairo_surface_t* surface)
109 {
110 if (fillSurface) cairo_surface_destroy (fillSurface);
111 fillSurface = cairo_image_surface_clone_from_image_surface (surface);
112 }
113
getCairoSurface()114 cairo_surface_t* Fill::getCairoSurface () {return fillSurface;}
115
116 /*
117 * End of class BWidgets::Fill
118 *****************************************************************************/
119
120
121 /*****************************************************************************
122 * Class BStyles::Font
123 *****************************************************************************/
124
Font()125 Font::Font () : Font ("Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL, 12.0) {}
Font(const std::string & family,const cairo_font_slant_t slant,const cairo_font_weight_t weight,const double size,TextAlign align,TextVAlign valign,double lineSpacing)126 Font::Font (const std::string& family, const cairo_font_slant_t slant, const cairo_font_weight_t weight, const double size,
127 TextAlign align, TextVAlign valign, double lineSpacing)
128 : fontFamily (family), fontSlant (slant), fontWeight (weight), fontSize (size),
129 textAlign (align), textVAlign (valign), textLineSpacing (lineSpacing) {}
130
setFontFamily(const std::string & family)131 void Font::setFontFamily (const std::string& family) {fontFamily = family;}
getFontFamily() const132 std::string Font::getFontFamily () const {return fontFamily;}
setFontSlant(const cairo_font_slant_t slant)133 void Font::setFontSlant (const cairo_font_slant_t slant) {fontSlant = slant;}
getFontSlant() const134 cairo_font_slant_t Font::getFontSlant () const {return fontSlant;}
setFontWeight(const cairo_font_weight_t weight)135 void Font::setFontWeight (const cairo_font_weight_t weight) {fontWeight = weight;}
getFontWeight() const136 cairo_font_weight_t Font::getFontWeight () const {return fontWeight;}
setTextAlign(const TextAlign align)137 void Font::setTextAlign (const TextAlign align) {textAlign = align;}
getTextAlign() const138 TextAlign Font::getTextAlign () const {return textAlign;}
setTextVAlign(const TextVAlign valign)139 void Font::setTextVAlign (const TextVAlign valign) {textVAlign = valign;}
getTextVAlign() const140 TextVAlign Font::getTextVAlign () const {return textVAlign;}
setLineSpacing(const double lineSpacing)141 void Font::setLineSpacing (const double lineSpacing) {textLineSpacing = lineSpacing;}
getLineSpacing() const142 double Font::getLineSpacing () const {return textLineSpacing;}
setFontSize(const double size)143 void Font::setFontSize (const double size) {fontSize = size;}
getFontSize() const144 double Font::getFontSize () const {return fontSize;}
145
getTextExtents(cairo_t * cr,const std::string & text) const146 cairo_text_extents_t Font::getTextExtents (cairo_t* cr, const std::string& text) const
147 {
148 if (cr && (! cairo_status (cr)))
149 {
150 cairo_save (cr);
151
152 cairo_text_extents_t ext;
153 cairo_select_font_face (cr, fontFamily.c_str (), fontSlant, fontWeight);
154 cairo_set_font_size (cr, fontSize);
155 cairo_text_extents (cr, text.c_str(), &ext);
156
157 cairo_restore (cr);
158 return ext;
159 }
160 else
161 {
162 return {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
163 }
164 }
165
166 /*
167 * End of class BWidgets::Font
168 *****************************************************************************/
169
170
171 /*****************************************************************************
172 * Class BStyles::StyleSet
173 *****************************************************************************/
174
StyleSet()175 StyleSet::StyleSet () {}
StyleSet(const std::string & name,const std::vector<Style> & styles)176 StyleSet::StyleSet (const std::string& name, const std::vector<Style>& styles) : stylesetName (name), styleVector (styles) {}
177
addStyle(const std::string & styleName,void * ptr)178 void StyleSet::addStyle (const std::string& styleName, void* ptr)
179 {
180 for (Style style : styleVector)
181 {
182 if (style.name == styleName)
183 {
184 // Overwrite existing style
185 std::cerr << "Msg from BStyles::StyleSet::addStyle(): Overwrite existing " << stylesetName << "/" << styleName
186 << "." << std:: endl;
187 style.stylePtr = ptr;
188 return;
189 }
190 }
191
192 // No hit for styleName? Append style to existing styleset
193 Style newStyle = {styleName, ptr};
194 styleVector.push_back (newStyle);
195 return;
196 }
197
removeStyle(const std::string & styleName)198 void StyleSet::removeStyle (const std::string& styleName)
199 {
200 for (std::vector<Style>::iterator it = styleVector.begin (); it !=styleVector.end (); ++it)
201 {
202 if (it->name == styleName) // @suppress("Field cannot be resolved")
203 {
204 // Delete existing style
205 styleVector.erase (it);
206 return;
207 }
208 }
209
210 // No hit?
211 std::cerr << "Msg from BStyles::StyleSet::removeStyle(): " << stylesetName << "/" << styleName
212 << " doesn't exist. Nothing to delete." << std:: endl;
213 return;
214 }
215
getStyle(const std::string & styleName)216 void* StyleSet::getStyle (const std::string& styleName)
217 {
218 void* ptr = nullptr;
219 for (Style style : styleVector)
220 {
221 if (style.name == "uses")
222 {
223 StyleSet* usedSet = (StyleSet*) style.stylePtr;
224 ptr = usedSet->getStyle (styleName);
225
226 }
227 if (style.name == styleName)
228 {
229 return ptr = style.stylePtr;
230 }
231 }
232
233 // No hit?
234 // if (!ptr) std::cerr << "Msg from BStyles::StyleSet::getStyle(): " << stylesetName << "/" << styleName << " doesn't exist." << std:: endl;
235 return ptr;
236 }
237
setName(const std::string & name)238 void StyleSet::setName (const std::string& name) {stylesetName = name;}
getName() const239 std::string StyleSet::getName () const {return stylesetName;}
240
241 /*
242 * End of class BWidgets::StyleSet
243 *****************************************************************************/
244
245 /*****************************************************************************
246 * Class BStyles::Theme
247 *****************************************************************************/
248
Theme()249 Theme::Theme () {};
Theme(const std::vector<StyleSet> & theme)250 Theme::Theme (const std::vector<StyleSet>& theme): stylesetVector (theme) {};
251
addStyle(const std::string & setName,const std::string & styleName,void * ptr)252 void Theme::addStyle (const std::string& setName, const std::string& styleName, void* ptr)
253 {
254 for (StyleSet styleSet : stylesetVector)
255 {
256 if (styleSet.getName () == setName)
257 {
258 styleSet.addStyle (styleName, ptr);
259 return;
260 }
261 }
262
263 // No hit for styleset? Append styleset to existing theme
264 StyleSet newSet = {setName, {{styleName, ptr}}};
265 stylesetVector.push_back (newSet);
266 }
267
removeStyle(const std::string & setName,const std::string & styleName)268 void Theme::removeStyle (const std::string& setName, const std::string& styleName)
269 {
270 for (StyleSet styleSet : stylesetVector)
271 {
272 if (styleSet.getName () == setName)
273 {
274 styleSet.removeStyle (styleName);
275 return;
276 }
277 }
278
279 // No hit?
280 // std::cerr << "Msg from BStyles::Theme::removeStyle(): " << setName << "/" << styleName
281 // << " doesn't exist. Nothing to delete." << std:: endl;
282 return;
283 }
284
getStyle(const std::string & setName,const std::string & styleName)285 void* Theme::getStyle (const std::string& setName, const std::string& styleName)
286 {
287 for (StyleSet styleSet : stylesetVector)
288 {
289 if (styleSet.getName () == setName)
290 {
291 return styleSet.getStyle (styleName);
292 }
293 }
294
295 // No hit?
296 // std::cerr << "Msg from BStyles::Theme::getStyle(): " << setName << "/" << styleName
297 // << " doesn't exist." << std:: endl;
298 return nullptr;
299 }
300
301 /*
302 * End of class BWidgets::Theme
303 *****************************************************************************/
304
305
306 }
307