F:/KPlato/koffice/libs/kformula/PaddedElement.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "elementtype.h"
00021 #include "PaddedElement.h"
00022 
00023 namespace KFormula {
00024 
00025 PaddedElement::PaddedElement( BasicElement* parent ) : SequenceElement( parent ),
00026                                                        m_widthType( NoSize ),
00027                                                        m_lspaceType( NoSize ),
00028                                                        m_heightType( NoSize ),
00029                                                        m_depthType( NoSize ),
00030                                                        m_widthRelative( false ),
00031                                                        m_lspaceRelative( false ),
00032                                                        m_heightRelative( false ),
00033                                                        m_depthRelative( false )
00034 {
00035 }
00036 
00041 void PaddedElement::calcSizes( const ContextStyle& context,
00042                                ContextStyle::TextStyle tstyle,
00043                                ContextStyle::IndexStyle istyle,
00044                                StyleAttributes& style )
00045 {
00046     double factor = style.sizeFactor();
00047 
00048     luPixel width = 0;
00049     luPixel height = 0;
00050     luPixel depth = 0;
00051     luPixel spaceBefore = 0;
00052 
00053     if ( !isEmpty() ) {
00054         // First, get content height and width
00055         for ( iterator it = begin(); it != end(); ++it ) {
00056             if ( it == begin() ) {
00057                 spaceBefore =
00058                     context.ptToPixelX( it->getElementType()->getSpaceBefore( context,
00059                                                                               tstyle,
00060                                                                               factor ) );
00061             }
00062             it->calcSizes( context, tstyle, istyle, style );
00063             width += it->getWidth() + spaceBefore;
00064             luPixel baseline = it->getBaseline();
00065             if ( baseline > -1 ) {
00066                 height = qMax( height, baseline );
00067                 depth = qMax( depth, it->getHeight() - baseline );
00068             }
00069             else {
00070                 luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor );
00071                 height = qMax( height, bl );
00072                 depth = qMax( depth, it->getHeight() - bl );
00073             }
00074         }
00075     }
00076     else {
00077         width = context.getEmptyRectWidth( factor );
00078         height = context.getEmptyRectHeight( factor );
00079         depth = 0;
00080     }
00081 
00082     luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 );
00083     luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left;
00084     luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth );
00085     luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height );
00086 
00087     // Check borders
00088     if ( right < 0 ) right = 0;
00089     if ( up + down < 0 ) up = down = 0;
00090     
00091     if ( ! isEmpty() ) {
00092         width = left;
00093         // Let's do all normal elements that have a base line.
00094         for ( iterator it = begin(); it != end(); ++it ) {
00095             it->calcSizes( context, tstyle, istyle, style );
00096             it->setX( width + spaceBefore );
00097             width += it->getWidth() + spaceBefore;
00098         }
00099 
00100         setWidth( right );
00101         setHeight( up + down );
00102         setBaseline( up );
00103         setChildrenPositions();
00104     }
00105     else {
00106         setWidth( right );
00107         setHeight( up + down );
00108         setBaseline( up );
00109     }
00110 }
00111 
00112 bool PaddedElement::readAttributesFromMathMLDom(const QDomElement& element)
00113 {
00114     if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) {
00115         return false;
00116     }
00117 
00118     QString widthStr = element.attribute( "width" ).stripWhiteSpace().lower();
00119     if ( ! widthStr.isNull() ) {
00120         m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative );
00121     }
00122     QString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower();
00123     if ( ! lspaceStr.isNull() ) {
00124         m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative );
00125     }
00126     QString heightStr = element.attribute( "height" ).stripWhiteSpace().lower();
00127     if ( ! heightStr.isNull() ) {
00128         m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative );
00129     }
00130     QString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower();
00131     if ( ! depthStr.isNull() ) {
00132         m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative );
00133     }
00134 
00135     return true;
00136 }
00137 
00138 void PaddedElement::writeMathMLAttributes( QDomElement& element ) const
00139 {
00140     writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative );
00141     writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative );
00142     writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative );
00143     writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative );
00144 }
00145 
00146 double PaddedElement::readSizeAttribute( const QString& str, SizeType* st, bool* relative )
00147 {
00148     if ( st == 0 ){
00149         return -1;
00150     }
00151     if ( str[0] == '+' || str[0] == '-' ) {
00152         *relative = true;
00153     }
00154     int index = str.find( "width" );
00155     if ( index != -1 ) {
00156         int index2 = str.find( "%" );
00157         if ( index2 != -1 ) {
00158             return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0;
00159         }
00160         return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize );
00161     }
00162     index = str.find( "height" );
00163     if ( index != -1 ) {
00164         int index2 = str.find( "%" );
00165         if ( index2 != -1 ) {
00166             return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0;
00167         }
00168         return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize );
00169     }
00170     index = str.find( "%" );
00171     if ( index != -1 ) {
00172         return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0;
00173     }
00174     index = str.find( "pt", 0, false );
00175     if ( index != -1 ) {
00176         return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize );
00177     }
00178     index = str.find( "mm", 0, false );
00179     if ( index != -1 ) {
00180         return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54;
00181     }
00182     index = str.find( "cm", 0, false );
00183     if ( index != -1 ) {
00184         return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54;
00185     }
00186     index = str.find( "in", 0, false );
00187     if ( index != -1 ) {
00188         return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0;
00189     }
00190     index = str.find( "em", 0, false );
00191     if ( index != -1 ) {
00192         return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
00193     }
00194     index = str.find( "ex", 0, false );
00195     if ( index != -1 ) {
00196         return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
00197     }
00198     index = str.find( "pc", 0, false );
00199     if ( index != -1 ) {
00200         return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0;
00201     }
00202     index = str.find( "px", 0, false );
00203     if ( index != -1 ) {
00204         return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize );
00205     }
00206     // If there's no unit, assume 'pt'
00207     return str2size( str, st, AbsoluteSize );
00208 }
00209 
00210 double PaddedElement::str2size( const QString& str, SizeType *st, SizeType type )
00211 {
00212     bool ok;
00213     double size = str.toDouble( &ok );
00214     if ( ok ) {
00215         if ( st ) {
00216             *st = type;
00217         }
00218         return size;
00219     }
00220     if ( st ) {
00221         *st = NoSize;
00222     }
00223     return -1;
00224 }
00225 
00226 void PaddedElement::writeSizeAttribute( QDomElement element, const QString& str,
00227                                         SizeType st, bool relative, double s ) const
00228 {
00229     QString prefix;
00230     if ( relative ) {
00231         s < 0 ? prefix = "-" : prefix = "+" ;
00232     }
00233     switch ( st ) {
00234     case WidthRelativeSize:
00235         element.setAttribute( str, prefix + QString( "%1 width" ).arg( s ) );
00236         break;
00237     case HeightRelativeSize:
00238         element.setAttribute( str, prefix + QString( "%1 height" ).arg( s ) );
00239     case AbsoluteSize:
00240         element.setAttribute( str, prefix + QString( "%1pt" ).arg( s ) );
00241         break;
00242     case RelativeSize:
00243         element.setAttribute( str, prefix + QString( "%1%" ).arg( s * 100.0 ) );
00244         break;
00245     case PixelSize:
00246         element.setAttribute( str, prefix + QString( "%1px" ).arg( s ) );
00247         break;
00248     default:
00249         break;
00250     }
00251 }
00252 
00253 luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type, 
00254                                  bool relative, double length, luPixel width,
00255                                  luPixel height, luPixel defvalue )
00256 {
00257     luPixel value = defvalue;
00258     switch ( type ) {
00259     case AbsoluteSize:
00260         if ( relative )
00261             value += context.ptToLayoutUnitPt ( length );
00262         else
00263             value = context.ptToLayoutUnitPt( length );
00264         break;
00265     case RelativeSize:
00266         if ( relative )
00267             value += length * value;
00268         else
00269             value *= length;
00270         break;
00271     case WidthRelativeSize:
00272         if ( relative )
00273             value += length * width;
00274         else
00275             value = length * width;
00276         break;
00277     case HeightRelativeSize:
00278         if ( relative )
00279             value += length * height;
00280         else
00281             value = length * height;
00282         break;
00283     case PixelSize:
00284         if ( relative )
00285             value += context.pixelToLayoutUnitX( length );
00286         else
00287             value = context.pixelToLayoutUnitX( length );
00288         break;
00289     default:
00290         break;
00291     }
00292     return value;
00293 }
00294 
00295 } // namespace KFormula

Généré le Wed Nov 22 23:41:01 2006 pour KPlato par  doxygen 1.5.1-p1