1 // -*- C++ -*-
2
3 /*
4 * Gnome Chemistry Utils
5 * gccv/equation.cc
6 *
7 * Copyright (C) 2014 Jean Bréfort <jean.brefort@normalesup.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 */
24
25 #include "config.h"
26 #include "canvas.h"
27 #include "equation.h"
28
29 namespace gccv {
30
Equation(Canvas * canvas,double x,double y)31 Equation::Equation (Canvas *canvas, double x, double y):
32 Rectangle (canvas, x, y, 0., 0.),
33 m_x (x), m_y (y), m_View (NULL),
34 m_Math (NULL),
35 m_Anchor (AnchorLineWest),
36 m_AutoTextColor (false),
37 m_AutoFont (false)
38 {
39 }
40
Equation(Group * parent,double x,double y,ItemClient * client)41 Equation::Equation (Group *parent, double x, double y, ItemClient *client):
42 Rectangle (parent, x, y, 0., 0., client),
43 m_x (x), m_y (y), m_View (NULL),
44 m_Math (NULL),
45 m_Anchor (AnchorLineWest),
46 m_AutoTextColor (false),
47 m_AutoFont (false)
48 {
49 }
50
~Equation()51 Equation::~Equation ()
52 {
53 if (m_View)
54 g_object_unref (m_View);
55 }
56
57 static GOColor last_color = 0;
58 static std::string last_font;
59
Draw(cairo_t * cr,bool is_vector) const60 void Equation::Draw (cairo_t *cr, bool is_vector) const
61 {
62 if (m_Math && (m_AutoFont || m_AutoTextColor)) {
63 LsmDomNode *node = lsm_dom_node_get_first_child (LSM_DOM_NODE (m_Math));
64 LsmDomElement *style = LSM_DOM_ELEMENT (lsm_dom_node_get_first_child (node));
65 char *value;
66 bool changed = false;
67 if (m_AutoFont) {
68 PangoFontDescription *font = GetCanvas ()->GetFont ();
69 if (font) {
70 char *desc = pango_font_description_to_string (font);
71 if (last_font != desc) {
72 last_font = desc;
73 if (pango_font_description_get_weight (font) >= PANGO_WEIGHT_BOLD) {
74 if (pango_font_description_get_style (font) == PANGO_STYLE_NORMAL)
75 lsm_dom_element_set_attribute (style, "mathvariant", "bold");
76 else
77 lsm_dom_element_set_attribute (style, "mathvariant", "bold-italic");
78 } else {
79 if (pango_font_description_get_style (font) == PANGO_STYLE_NORMAL)
80 lsm_dom_element_set_attribute (style, "mathvariant", "normal");
81 else
82 lsm_dom_element_set_attribute (style, "mathvariant", "italic");
83 }
84
85 lsm_dom_element_set_attribute (style, "mathfamily",
86 pango_font_description_get_family (font));
87
88 value = g_strdup_printf ("%gpt", pango_units_to_double (
89 pango_font_description_get_size (font)));
90 lsm_dom_element_set_attribute (style, "mathsize", value);
91 g_free (value);
92 }
93 g_free (desc);
94 }
95 }
96 if (m_AutoTextColor) {
97 GOColor color = GetCanvas ()->GetColor ();
98 if (color != last_color) {
99 last_color = color;
100 changed = true;
101 value = g_strdup_printf ("#%02x%02x%02x",
102 GO_COLOR_UINT_R (color),
103 GO_COLOR_UINT_G (color),
104 GO_COLOR_UINT_B (color));
105 lsm_dom_element_set_attribute (style, "mathcolor", value);
106 g_free (value);
107 }
108 }
109 if (changed)
110 const_cast < gccv::Equation * > (this)->SetPosition (m_x, m_y);
111 }
112 Rectangle::Draw (cr, is_vector);
113 if (m_View) {
114 double x, y;
115 GetPosition (x, y);
116 cairo_save (cr);
117 cairo_translate (cr, x, y);
118 cairo_scale (cr, 4./3., 4./3.);
119 lsm_dom_view_render (m_View, cr, 0., 0.);
120 cairo_restore (cr);
121 cairo_new_path (cr);
122 }
123 }
124
SetPosition(double x,double y)125 void Equation::SetPosition (double x, double y)
126 {
127 m_x = x;
128 m_y = y;
129 if (m_View)
130 g_object_unref (m_View);
131 m_View = (m_Math)? lsm_dom_document_create_view (const_cast < LsmDomDocument * > (m_Math)): NULL;
132 double w, h, bl;
133 if (m_View) {
134 lsm_dom_view_get_size (m_View, &w, &h, &bl);
135 w /= 0.75;
136 h /= 0.75;
137 } else {
138 w = 2.;
139 h = bl = 10.;
140 }
141 // Horizontal position
142 switch (m_Anchor) {
143 default:
144 case AnchorNorth:
145 case AnchorLine:
146 case AnchorCenter:
147 case AnchorSouth:
148 x -= w / 2.;
149 break;
150 case AnchorNorthWest:
151 case AnchorLineWest:
152 case AnchorWest:
153 case AnchorSouthWest:
154 break;
155 case AnchorNorthEast:
156 case AnchorLineEast:
157 case AnchorEast:
158 case AnchorSouthEast:
159 x-= w;
160 break;
161 }
162 // Vertical position
163 switch (m_Anchor) {
164 default:
165 case AnchorLine:
166 case AnchorLineWest:
167 case AnchorLineEast: {
168 y -= bl;
169 break;
170 }
171 case AnchorCenter:
172 case AnchorWest:
173 case AnchorEast:
174 y -= h / 2.;
175 break;
176 case AnchorNorth:
177 case AnchorNorthWest:
178 case AnchorNorthEast:
179 break;
180 case AnchorSouth:
181 case AnchorSouthWest:
182 case AnchorSouthEast:
183 y -= h;
184 break;
185 }
186 Rectangle::SetPosition (x, y, w, h);
187 }
188
189 } // namespace gccv
190