lib

styleelement.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "basicelement.h"
21#include "styleelement.h"
22
23KFORMULA_NAMESPACE_BEGIN
24
25StyleElement::StyleElement( BasicElement* parent ) : TokenStyleElement( parent ),
26 m_scriptMinSizeType( NoSize ),
27 m_veryVeryThinMathSpaceType( NoSize ),
28 m_veryThinMathSpaceType( NoSize ),
29 m_thinMathSpaceType( NoSize ),
30 m_mediumMathSpaceType( NoSize ),
31 m_thickMathSpaceType( NoSize ),
32 m_veryThickMathSpaceType( NoSize ),
33 m_veryVeryThickMathSpaceType( NoSize ),
34 m_customScriptLevel( false ),
35 m_relativeScriptLevel( false ),
36 m_customDisplayStyle( false ),
37 m_customScriptSizeMultiplier( false ),
38 m_customBackground( false )
39{
40}
41
42bool StyleElement::readAttributesFromMathMLDom( const TQDomElement& element )
43{
45 return false;
46 }
47
48 TQString scriptlevelStr = element.attribute( "scriptlevel" );
49 if ( ! scriptlevelStr.isNull() ) {
50 if ( scriptlevelStr[0] == '+' || scriptlevelStr[0] == '-' ) {
51 m_relativeScriptLevel = true;
52 }
53 bool ok;
54 m_scriptLevel = scriptlevelStr.toInt( &ok );
55 if ( ! ok ) {
56 kdWarning( DEBUGID ) << "Invalid scriptlevel attribute value: "
57 << scriptlevelStr << endl;
58 }
59 else {
60 m_customScriptLevel = true;
61 }
62 }
63 TQString displaystyleStr = element.attribute( "displaystyle" );
64 if ( ! displaystyleStr.isNull() ) {
65 if ( displaystyleStr.lower() == "true" ) {
66 m_displayStyle = true;
67 }
68 else {
69 m_displayStyle = false;
70 }
71 m_customDisplayStyle = true;
72 }
73 TQString scriptsizemultiplierStr = element.attribute( "scriptsizemultiplier" );
74 if ( ! scriptsizemultiplierStr.isNull() ) {
75 bool ok;
76 m_scriptSizeMultiplier = scriptsizemultiplierStr.toDouble( &ok );
77 if ( ! ok ) {
78 kdWarning( DEBUGID ) << "Invalid scriptsizemultiplier attribute value: "
79 << scriptsizemultiplierStr << endl;
80 }
81 else {
82 m_customScriptSizeMultiplier = true;
83 }
84 }
85 TQString scriptminsizeStr = element.attribute( "scriptminsize" );
86 if ( ! scriptminsizeStr.isNull() ) {
87 readSizeAttribute( scriptminsizeStr, &m_scriptMinSizeType, &m_scriptMinSize );
88 }
89 TQString backgroundStr = element.attribute( "background" );
90 if ( ! backgroundStr.isNull() ) {
91 // TODO: tranparent background
92 m_customBackground = true;
93 if ( backgroundStr[0] != '#' ) {
94 m_background = TQColor( getHtmlColor( backgroundStr ) );
95 }
96 else {
97 m_background = TQColor( backgroundStr );
98 }
99 }
100 TQString veryverythinmathspaceStr = element.attribute( "veryverythinmathspace" );
101 if ( ! veryverythinmathspaceStr.isNull() ) {
102 readSizeAttribute( veryverythinmathspaceStr, &m_veryVeryThinMathSpaceType, &m_veryVeryThinMathSpace );
103 }
104 TQString verythinmathspaceStr = element.attribute( "verythinmathspace" );
105 if ( ! verythinmathspaceStr.isNull() ) {
106 readSizeAttribute( verythinmathspaceStr, &m_veryThinMathSpaceType, &m_veryThinMathSpace );
107 }
108 TQString thinmathspaceStr = element.attribute( "thinmathspace" );
109 if ( ! thinmathspaceStr.isNull() ) {
110 readSizeAttribute( thinmathspaceStr, &m_thinMathSpaceType, &m_thinMathSpace );
111 }
112 TQString mediummathspaceStr = element.attribute( "mediummathspace" );
113 if ( ! mediummathspaceStr.isNull() ) {
114 readSizeAttribute( mediummathspaceStr, &m_mediumMathSpaceType, &m_mediumMathSpace );
115 }
116 TQString thickmathspaceStr = element.attribute( "thickmathspace" );
117 if ( ! thickmathspaceStr.isNull() ) {
118 readSizeAttribute( thickmathspaceStr, &m_thickMathSpaceType, &m_thickMathSpace );
119 }
120 TQString verythickmathspaceStr = element.attribute( "verythickmathspace" );
121 if ( ! verythickmathspaceStr.isNull() ) {
122 readSizeAttribute( verythickmathspaceStr, &m_veryThickMathSpaceType, &m_veryThickMathSpace );
123 }
124 TQString veryverythickmathspaceStr = element.attribute( "veryverythickmathspace" );
125 if ( ! veryverythickmathspaceStr.isNull() ) {
126 readSizeAttribute( veryverythickmathspaceStr, &m_veryVeryThickMathSpaceType, &m_veryVeryThickMathSpace );
127 }
129}
130
131void StyleElement::writeMathMLAttributes( TQDomElement& element ) const
132{
133 if ( m_customScriptLevel ) {
134 TQString prefix;
135 if ( m_relativeScriptLevel && m_scriptLevel >= 0 ) {
136 prefix = "+";
137 }
138 element.setAttribute( "scriptlevel", prefix + TQString( "%1" ).arg( m_scriptLevel ) );
139 }
140 if ( m_customDisplayStyle ) {
141 element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" );
142 }
143 if ( m_customScriptSizeMultiplier ) {
144 element.setAttribute( "scriptsizemultiplier", TQString( "%1" ).arg( m_scriptSizeMultiplier ) );
145 }
146 writeSizeAttribute( element, "scriptminsize", m_scriptMinSizeType, m_scriptMinSize );
147 if ( m_customBackground ) {
148 element.setAttribute( "background", m_background.name() );
149 }
150 writeSizeAttribute( element, "veryverythinmathspace", m_veryVeryThinMathSpaceType, m_veryVeryThinMathSpace );
151 writeSizeAttribute( element, "verythinmathspace", m_veryThinMathSpaceType, m_veryThinMathSpace );
152 writeSizeAttribute( element, "thinmathspace", m_thinMathSpaceType, m_thinMathSpace );
153 writeSizeAttribute( element, "mediummathspace", m_mediumMathSpaceType, m_mediumMathSpace );
154 writeSizeAttribute( element, "thickmathspace", m_thickMathSpaceType, m_thickMathSpace );
155 writeSizeAttribute( element, "verythickmathspace", m_veryThickMathSpaceType, m_veryThickMathSpace );
156 writeSizeAttribute( element, "veryverythickmathspace", m_veryVeryThickMathSpaceType, m_veryVeryThickMathSpace );
157
158 inherited::writeMathMLAttributes( element );
159}
160
161
162void StyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style )
163{
164 if ( m_customScriptLevel ) {
165 if ( m_relativeScriptLevel ) {
166 style.setScriptLevel( style.scriptLevel() + m_scriptLevel );
167 }
168 else {
169 style.setScriptLevel( m_scriptLevel );
170 }
171 }
172 else {
173 style.setScriptLevel( style.scriptLevel() );
174 }
175 if ( m_customDisplayStyle || style.customDisplayStyle() ) {
176 style.setCustomDisplayStyle( true );
177 if ( m_customDisplayStyle ) {
178 style.setDisplayStyle( m_displayStyle );
179 }
180 else {
181 style.setDisplayStyle( style.displayStyle() );
182 }
183 }
184 else {
185 style.setCustomDisplayStyle( false );
186 }
187 if ( m_customScriptSizeMultiplier ) {
188 style.setScriptSizeMultiplier( m_scriptSizeMultiplier );
189 }
190 else {
191 style.setScriptSizeMultiplier( style.scriptSizeMultiplier() );
192 }
193
194 // Get scriptminsize attribute in absolute units, so we don't depend on
195 // context to get the default value
196 double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
197 double size = style.scriptMinSize();
198 switch ( m_scriptMinSizeType ) {
199 case AbsoluteSize:
200 size = m_scriptMinSize;
201 case RelativeSize:
202 size = m_scriptMinSize * basesize;
203 case PixelSize:
204 size = context.pixelXToPt( m_scriptMinSize );
205 default:
206 break;
207 }
208 style.setScriptMinSize( size );
209
210 style.setVeryVeryThinMathSpace( sizeFactor( context,
211 m_veryVeryThinMathSpaceType,
212 m_veryVeryThinMathSpace,
213 style.veryVeryThinMathSpace() ));
214 style.setVeryThinMathSpace( sizeFactor( context, m_veryThinMathSpaceType,
215 m_veryThinMathSpace,
216 style.veryThinMathSpace() ));
217 style.setThinMathSpace( sizeFactor( context, m_thinMathSpaceType,
218 m_thinMathSpace,
219 style.thinMathSpace() ));
220 style.setMediumMathSpace( sizeFactor( context, m_mediumMathSpaceType,
221 m_mediumMathSpace,
222 style.mediumMathSpace() ));
223 style.setThickMathSpace( sizeFactor( context, m_thickMathSpaceType,
224 m_thickMathSpace,
225 style.thickMathSpace() ));
226 style.setVeryThickMathSpace( sizeFactor( context, m_veryThickMathSpaceType,
227 m_veryThickMathSpace,
228 style.veryThickMathSpace() ));
229 style.setVeryVeryThickMathSpace( sizeFactor( context,
230 m_veryVeryThickMathSpaceType,
231 m_veryVeryThickMathSpace,
232 style.veryVeryThickMathSpace() ));
233 inherited::setStyleSize( context, style );
234}
235
236double StyleElement::sizeFactor( const ContextStyle& context, SizeType st,
237 double length, double defvalue )
238{
239 double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
240 switch ( st ) {
241 case AbsoluteSize:
242 return length / basesize;
243 case RelativeSize:
244 return length;
245 case PixelSize:
246 return context.pixelXToPt( length ) / basesize;
247 default:
248 break;
249 }
250 return defvalue;
251}
252
253void StyleElement::setStyleVariant( StyleAttributes& style )
254{
255 if ( customMathVariant() ) {
256 style.setCustomMathVariant ( true );
257 style.setCustomFontWeight( false );
258 style.setCustomFontStyle( false );
259 style.setCustomFont( false );
260 if ( customMathVariant() ) {
261 style.setCharFamily ( charFamily() );
262 style.setCharStyle( charStyle() );
263 }
264 else {
265 style.setCharFamily( style.charFamily() );
266 style.setCharStyle( style.charStyle() );
267 }
268 }
269 else {
270 style.setCustomMathVariant( false );
271 if ( customFontFamily() ) {
272 style.setCustomFont( true );
273 style.setFont( TQFont(fontFamily()) );
274 }
275
276 bool fontweight = false;
277 if ( customFontWeight() || style.customFontWeight() ) {
278 style.setCustomFontWeight( true );
279 if ( customFontWeight() ) {
280 fontweight = fontWeight();
281 }
282 else {
283 fontweight = style.fontWeight();
284 }
285 style.setFontWeight( fontweight );
286 }
287 else {
288 style.setCustomFontWeight( false );
289 }
290
291 bool fontstyle = false;
292 if ( customFontStyle() || style.customFontStyle() ) {
293 style.setCustomFontStyle( true );
294 if ( customFontStyle() ) {
295 fontstyle = fontStyle();
296 }
297 else {
298 fontstyle = style.fontStyle();
299 }
300 style.setFontStyle( fontstyle );
301 }
302 else {
303 style.setCustomFontStyle( false );
304 }
305
306 if ( fontweight && fontstyle ) {
307 style.setCharStyle( boldItalicChar );
308 }
309 else if ( fontweight && ! fontstyle ) {
310 style.setCharStyle( boldChar );
311 }
312 else if ( ! fontweight && fontstyle ) {
313 style.setCharStyle( italicChar );
314 }
315 else {
316 style.setCharStyle( normalChar );
317 }
318 }
319}
320
321void StyleElement::setStyleBackground( StyleAttributes& style )
322{
323 if ( customMathBackground() ) {
324 style.setBackground( mathBackground() );
325 }
326 else if ( m_customBackground ) {
327 style.setBackground( m_background );
328 }
329 else {
330 style.setBackground( style.background() );
331 }
332}
333
334void StyleElement::resetStyle( StyleAttributes& style )
335{
336 inherited::resetStyle( style );
337 style.resetScriptLevel();
338 style.resetScriptSizeMultiplier();
339 style.resetScriptMinSize();
340 style.resetVeryVeryThinMathSpace();
341 style.resetVeryThinMathSpace();
342 style.resetThinMathSpace();
343 style.resetMediumMathSpace();
344 style.resetThickMathSpace();
345 style.resetVeryThickMathSpace();
346 style.resetVeryVeryThickMathSpace();
347 style.resetDisplayStyle();
348}
349
350void StyleElement::readSizeAttribute( const TQString& str, SizeType* st, double* s )
351{
352 if ( st == 0 || s == 0 ){
353 return;
354 }
355 if ( str == "small" ) {
356 *st = RelativeSize;
357 *s = 0.8; // ### Arbitrary size
358 }
359 else if ( str == "normal" ) {
360 *st = RelativeSize;
361 *s = 1.0;
362 }
363 else if ( str == "big" ) {
364 *st = RelativeSize;
365 *s = 1.2; // ### Arbitrary size
366 }
367 else {
368 *s = getSize( str, st );
369 }
370}
371
372void StyleElement::writeSizeAttribute( TQDomElement element, const TQString& str, SizeType st, double s ) const
373{
374 switch ( st ) {
375 case AbsoluteSize:
376 element.setAttribute( str, TQString( "%1pt" ).arg( s ) );
377 break;
378 case RelativeSize:
379 element.setAttribute( str, TQString( "%1%" ).arg( s * 100.0 ) );
380 break;
381 case PixelSize:
382 element.setAttribute( str, TQString( "%1px" ).arg( s ) );
383 break;
384 default:
385 break;
386 }
387}
388
389
390KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual bool readAttributesFromMathMLDom(const TQDomElement &element)
Reads our attributes from the MathML element.
double getSize(const TQString &str, SizeType *st)
Utility function that sets the size type and returns the size value from a MathML attribute string wi...
Contains all the style information for the formela.
This class handles mathematical style attributes common to token elements, as explained in MathML Spe...
TQString getHtmlColor(const TQString &colorStr)
Return RGB string from HTML Colors.
virtual bool readAttributesFromMathMLDom(const TQDomElement &element)
Reads our attributes from the MathML element.