summaryrefslogtreecommitdiffstats
path: root/lib/kformula/paddedelement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kformula/paddedelement.cpp')
-rw-r--r--lib/kformula/paddedelement.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/lib/kformula/paddedelement.cpp b/lib/kformula/paddedelement.cpp
new file mode 100644
index 000000000..e4f28ce71
--- /dev/null
+++ b/lib/kformula/paddedelement.cpp
@@ -0,0 +1,296 @@
+/* This file is part of the KDE project
+ Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "elementtype.h"
+#include "paddedelement.h"
+
+KFORMULA_NAMESPACE_BEGIN
+
+PaddedElement::PaddedElement( BasicElement* parent ) : SequenceElement( parent ),
+ m_widthType( NoSize ),
+ m_lspaceType( NoSize ),
+ m_heightType( NoSize ),
+ m_depthType( NoSize ),
+ m_widthRelative( false ),
+ m_lspaceRelative( false ),
+ m_heightRelative( false ),
+ m_depthRelative( false )
+{
+}
+
+/**
+ * Calculates our width and height and
+ * our children's parentPosition.
+ */
+void PaddedElement::calcSizes( const ContextStyle& context,
+ ContextStyle::TextStyle tstyle,
+ ContextStyle::IndexStyle istyle,
+ StyleAttributes& style )
+{
+ double factor = style.sizeFactor();
+
+ luPixel width = 0;
+ luPixel height = 0;
+ luPixel depth = 0;
+
+ if ( !isEmpty() ) {
+ // First, get content height and width
+ for ( iterator it = begin(); it != end(); ++it ) {
+ luPixel spaceBefore = 0;
+ if ( it == begin() ) {
+ spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
+ }
+ it->calcSizes( context, tstyle, istyle, style );
+ width += it->getWidth() + spaceBefore;
+ luPixel baseline = it->getBaseline();
+ if ( baseline > -1 ) {
+ height = TQMAX( height, baseline );
+ depth = TQMAX( depth, it->getHeight() - baseline );
+ }
+ else {
+ luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor );
+ height = TQMAX( height, bl );
+ depth = TQMAX( depth, it->getHeight() - bl );
+ }
+ }
+ }
+ else {
+ width = context.getEmptyRectWidth( factor );
+ height = context.getEmptyRectHeight( factor );
+ depth = 0;
+ }
+
+ luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 );
+ luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left;
+ luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth );
+ luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height );
+
+ // Check borders
+ if ( right < 0 ) right = 0;
+ if ( up + down < 0 ) up = down = 0;
+
+ if ( ! isEmpty() ) {
+ width = left;
+ // Let's do all normal elements that have a base line.
+ for ( iterator it = begin(); it != end(); ++it ) {
+ luPixel spaceBefore = 0;
+ if ( it == begin() ) {
+ spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
+ }
+ it->calcSizes( context, tstyle, istyle, style );
+ it->setX( width + spaceBefore );
+ width += it->getWidth() + spaceBefore;
+ }
+
+ setWidth( right );
+ setHeight( up + down );
+ setBaseline( up );
+ setChildrenPositions();
+ }
+ else {
+ setWidth( right );
+ setHeight( up + down );
+ setBaseline( up );
+ }
+}
+
+bool PaddedElement::readAttributesFromMathMLDom(const TQDomElement& element)
+{
+ if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) {
+ return false;
+ }
+
+ TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower();
+ if ( ! widthStr.isNull() ) {
+ m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative );
+ }
+ TQString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower();
+ if ( ! lspaceStr.isNull() ) {
+ m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative );
+ }
+ TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower();
+ if ( ! heightStr.isNull() ) {
+ m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative );
+ }
+ TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower();
+ if ( ! depthStr.isNull() ) {
+ m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative );
+ }
+
+ return true;
+}
+
+void PaddedElement::writeMathMLAttributes( TQDomElement& element ) const
+{
+ writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative );
+ writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative );
+ writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative );
+ writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative );
+}
+
+double PaddedElement::readSizeAttribute( const TQString& str, SizeType* st, bool* relative )
+{
+ if ( st == 0 ){
+ return -1;
+ }
+ if ( str[0] == '+' || str[0] == '-' ) {
+ *relative = true;
+ }
+ int index = str.find( "width" );
+ if ( index != -1 ) {
+ int index2 = str.find( "%" );
+ if ( index2 != -1 ) {
+ return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0;
+ }
+ return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize );
+ }
+ index = str.find( "height" );
+ if ( index != -1 ) {
+ int index2 = str.find( "%" );
+ if ( index2 != -1 ) {
+ return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0;
+ }
+ return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize );
+ }
+ index = str.find( "%" );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0;
+ }
+ index = str.find( "pt", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize );
+ }
+ index = str.find( "mm", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54;
+ }
+ index = str.find( "cm", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54;
+ }
+ index = str.find( "in", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0;
+ }
+ index = str.find( "em", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
+ }
+ index = str.find( "ex", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
+ }
+ index = str.find( "pc", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0;
+ }
+ index = str.find( "px", 0, false );
+ if ( index != -1 ) {
+ return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize );
+ }
+ // If there's no unit, assume 'pt'
+ return str2size( str, st, AbsoluteSize );
+}
+
+double PaddedElement::str2size( const TQString& str, SizeType *st, SizeType type )
+{
+ bool ok;
+ double size = str.toDouble( &ok );
+ if ( ok ) {
+ if ( st ) {
+ *st = type;
+ }
+ return size;
+ }
+ if ( st ) {
+ *st = NoSize;
+ }
+ return -1;
+}
+
+void PaddedElement::writeSizeAttribute( TQDomElement element, const TQString& str,
+ SizeType st, bool relative, double s ) const
+{
+ TQString prefix;
+ if ( relative ) {
+ s < 0 ? prefix = "-" : prefix = "+" ;
+ }
+ switch ( st ) {
+ case WidthRelativeSize:
+ element.setAttribute( str, prefix + TQString( "%1 width" ).arg( s ) );
+ break;
+ case HeightRelativeSize:
+ element.setAttribute( str, prefix + TQString( "%1 height" ).arg( s ) );
+ case AbsoluteSize:
+ element.setAttribute( str, prefix + TQString( "%1pt" ).arg( s ) );
+ break;
+ case RelativeSize:
+ element.setAttribute( str, prefix + TQString( "%1%" ).arg( s * 100.0 ) );
+ break;
+ case PixelSize:
+ element.setAttribute( str, prefix + TQString( "%1px" ).arg( s ) );
+ break;
+ default:
+ break;
+ }
+}
+
+luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type,
+ bool relative, double length, luPixel width,
+ luPixel height, luPixel defvalue )
+{
+ luPixel value = defvalue;
+ switch ( type ) {
+ case AbsoluteSize:
+ if ( relative )
+ value += context.ptToLayoutUnitPt ( length );
+ else
+ value = context.ptToLayoutUnitPt( length );
+ break;
+ case RelativeSize:
+ if ( relative )
+ value += length * value;
+ else
+ value *= length;
+ break;
+ case WidthRelativeSize:
+ if ( relative )
+ value += length * width;
+ else
+ value = length * width;
+ break;
+ case HeightRelativeSize:
+ if ( relative )
+ value += length * height;
+ else
+ value = length * height;
+ break;
+ case PixelSize:
+ if ( relative )
+ value += context.pixelToLayoutUnitX( length );
+ else
+ value = context.pixelToLayoutUnitX( length );
+ break;
+ default:
+ break;
+ }
+ return value;
+}
+
+KFORMULA_NAMESPACE_END