lib

paddedelement.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 "elementtype.h"
21#include "paddedelement.h"
22
23KFORMULA_NAMESPACE_BEGIN
24
25PaddedElement::PaddedElement( BasicElement* parent ) : SequenceElement( parent ),
26 m_widthType( NoSize ),
27 m_lspaceType( NoSize ),
28 m_heightType( NoSize ),
29 m_depthType( NoSize ),
30 m_widthRelative( false ),
31 m_lspaceRelative( false ),
32 m_heightRelative( false ),
33 m_depthRelative( false )
34{
35}
36
41void PaddedElement::calcSizes( const ContextStyle& context,
43 ContextStyle::IndexStyle istyle,
44 StyleAttributes& style )
45{
46 double factor = style.sizeFactor();
47
48 luPixel width = 0;
49 luPixel height = 0;
50 luPixel depth = 0;
51
52 if ( !isEmpty() ) {
53 // First, get content height and width
54 for ( iterator it = begin(); it != end(); ++it ) {
55 luPixel spaceBefore = 0;
56 if ( it == begin() ) {
57 spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
58 }
59 it->calcSizes( context, tstyle, istyle, style );
60 width += it->getWidth() + spaceBefore;
61 luPixel baseline = it->getBaseline();
62 if ( baseline > -1 ) {
63 height = TQMAX( height, baseline );
64 depth = TQMAX( depth, it->getHeight() - baseline );
65 }
66 else {
67 luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor );
68 height = TQMAX( height, bl );
69 depth = TQMAX( depth, it->getHeight() - bl );
70 }
71 }
72 }
73 else {
74 width = context.getEmptyRectWidth( factor );
75 height = context.getEmptyRectHeight( factor );
76 depth = 0;
77 }
78
79 luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 );
80 luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left;
81 luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth );
82 luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height );
83
84 // Check borders
85 if ( right < 0 ) right = 0;
86 if ( up + down < 0 ) up = down = 0;
87
88 if ( ! isEmpty() ) {
89 width = left;
90 // Let's do all normal elements that have a base line.
91 for ( iterator it = begin(); it != end(); ++it ) {
92 luPixel spaceBefore = 0;
93 if ( it == begin() ) {
94 spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
95 }
96 it->calcSizes( context, tstyle, istyle, style );
97 it->setX( width + spaceBefore );
98 width += it->getWidth() + spaceBefore;
99 }
100
101 setWidth( right );
102 setHeight( up + down );
103 setBaseline( up );
105 }
106 else {
107 setWidth( right );
108 setHeight( up + down );
109 setBaseline( up );
110 }
111}
112
113bool PaddedElement::readAttributesFromMathMLDom(const TQDomElement& element)
114{
116 return false;
117 }
118
119 TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower();
120 if ( ! widthStr.isNull() ) {
121 m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative );
122 }
123 TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower();
124 if ( ! lspaceStr.isNull() ) {
125 m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative );
126 }
127 TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower();
128 if ( ! heightStr.isNull() ) {
129 m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative );
130 }
131 TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower();
132 if ( ! depthStr.isNull() ) {
133 m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative );
134 }
135
136 return true;
137}
138
139void PaddedElement::writeMathMLAttributes( TQDomElement& element ) const
140{
141 writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative );
142 writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative );
143 writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative );
144 writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative );
145}
146
147double PaddedElement::readSizeAttribute( const TQString& str, SizeType* st, bool* relative )
148{
149 if ( st == 0 ){
150 return -1;
151 }
152 if ( str[0] == '+' || str[0] == '-' ) {
153 *relative = true;
154 }
155 int index = str.find( "width" );
156 if ( index != -1 ) {
157 int index2 = str.find( "%" );
158 if ( index2 != -1 ) {
159 return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0;
160 }
161 return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize );
162 }
163 index = str.find( "height" );
164 if ( index != -1 ) {
165 int index2 = str.find( "%" );
166 if ( index2 != -1 ) {
167 return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0;
168 }
169 return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize );
170 }
171 index = str.find( "%" );
172 if ( index != -1 ) {
173 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0;
174 }
175 index = str.find( "pt", 0, false );
176 if ( index != -1 ) {
177 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize );
178 }
179 index = str.find( "mm", 0, false );
180 if ( index != -1 ) {
181 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54;
182 }
183 index = str.find( "cm", 0, false );
184 if ( index != -1 ) {
185 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54;
186 }
187 index = str.find( "in", 0, false );
188 if ( index != -1 ) {
189 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0;
190 }
191 index = str.find( "em", 0, false );
192 if ( index != -1 ) {
193 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
194 }
195 index = str.find( "ex", 0, false );
196 if ( index != -1 ) {
197 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
198 }
199 index = str.find( "pc", 0, false );
200 if ( index != -1 ) {
201 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0;
202 }
203 index = str.find( "px", 0, false );
204 if ( index != -1 ) {
205 return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize );
206 }
207 // If there's no unit, assume 'pt'
208 return str2size( str, st, AbsoluteSize );
209}
210
211double PaddedElement::str2size( const TQString& str, SizeType *st, SizeType type )
212{
213 bool ok;
214 double size = str.toDouble( &ok );
215 if ( ok ) {
216 if ( st ) {
217 *st = type;
218 }
219 return size;
220 }
221 if ( st ) {
222 *st = NoSize;
223 }
224 return -1;
225}
226
227void PaddedElement::writeSizeAttribute( TQDomElement element, const TQString& str,
228 SizeType st, bool relative, double s ) const
229{
230 TQString prefix;
231 if ( relative ) {
232 s < 0 ? prefix = "-" : prefix = "+" ;
233 }
234 switch ( st ) {
235 case WidthRelativeSize:
236 element.setAttribute( str, prefix + TQString( "%1 width" ).arg( s ) );
237 break;
238 case HeightRelativeSize:
239 element.setAttribute( str, prefix + TQString( "%1 height" ).arg( s ) );
240 case AbsoluteSize:
241 element.setAttribute( str, prefix + TQString( "%1pt" ).arg( s ) );
242 break;
243 case RelativeSize:
244 element.setAttribute( str, prefix + TQString( "%1%" ).arg( s * 100.0 ) );
245 break;
246 case PixelSize:
247 element.setAttribute( str, prefix + TQString( "%1px" ).arg( s ) );
248 break;
249 default:
250 break;
251 }
252}
253
254luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type,
255 bool relative, double length, luPixel width,
256 luPixel height, luPixel defvalue )
257{
258 luPixel value = defvalue;
259 switch ( type ) {
260 case AbsoluteSize:
261 if ( relative )
262 value += context.ptToLayoutUnitPt ( length );
263 else
264 value = context.ptToLayoutUnitPt( length );
265 break;
266 case RelativeSize:
267 if ( relative )
268 value += length * value;
269 else
270 value *= length;
271 break;
272 case WidthRelativeSize:
273 if ( relative )
274 value += length * width;
275 else
276 value = length * width;
277 break;
278 case HeightRelativeSize:
279 if ( relative )
280 value += length * height;
281 else
282 value = length * height;
283 break;
284 case PixelSize:
285 if ( relative )
286 value += context.pixelToLayoutUnitX( length );
287 else
288 value = context.pixelToLayoutUnitX( length );
289 break;
290 default:
291 break;
292 }
293 return value;
294}
295
296KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual bool readAttributesFromMathMLDom(const TQDomElement &element)
Reads our attributes from the MathML element.
Contains all the style information for the formela.
TextStyle
Textstyles like in TeX.
int ptToPixelX(double pt) const
Basic pt to pixel and pixel to pt conversions, valid at any zoom level, as well as at the Layout Unit...
static double ptToLayoutUnitPt(double pt)
Not zoom dependent.
int pixelToLayoutUnitX(int x) const
The "[zoomed] view pixel" -> "layout unit pixel" conversions.
The element that contains a number of children.
virtual luPt getSpaceBefore(const ContextStyle &, ContextStyle::TextStyle, double)
Space around sequence.
virtual void setChildrenPositions()
Sets the childrens' positions after their size has been calculated.
TDEAction * up(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)