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