/* This file is part of the KDE project Copyright (C) 2006 Alfredo Beaumont Sainz 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* tqparent ) : SequenceElement( tqparent ), 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 tqchildren'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" ).tqarg( s ) ); break; case HeightRelativeSize: element.setAttribute( str, prefix + TQString( "%1 height" ).tqarg( s ) ); case AbsoluteSize: element.setAttribute( str, prefix + TQString( "%1pt" ).tqarg( s ) ); break; case RelativeSize: element.setAttribute( str, prefix + TQString( "%1%" ).tqarg( s * 100.0 ) ); break; case PixelSize: element.setAttribute( str, prefix + TQString( "%1px" ).tqarg( 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