00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "elementtype.h"
00021 #include "paddedelement.h"
00022
00023 KFORMULA_NAMESPACE_BEGIN
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
00052 if ( !isEmpty() ) {
00053
00054 for ( iterator it = begin(); it != end(); ++it ) {
00055 luPixel spaceBefore = 0;
00056 if ( it == begin() ) {
00057 spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
00058 }
00059 it->calcSizes( context, tstyle, istyle, style );
00060 width += it->getWidth() + spaceBefore;
00061 luPixel baseline = it->getBaseline();
00062 if ( baseline > -1 ) {
00063 height = QMAX( height, baseline );
00064 depth = QMAX( depth, it->getHeight() - baseline );
00065 }
00066 else {
00067 luPixel bl = it->getHeight()/2 + context.axisHeight( tstyle, factor );
00068 height = QMAX( height, bl );
00069 depth = QMAX( depth, it->getHeight() - bl );
00070 }
00071 }
00072 }
00073 else {
00074 width = context.getEmptyRectWidth( factor );
00075 height = context.getEmptyRectHeight( factor );
00076 depth = 0;
00077 }
00078
00079 luPixel left = calcSize( context, m_lspaceType, m_lspaceRelative, m_lspace, width, height, 0 );
00080 luPixel right = calcSize( context, m_widthType, m_widthRelative, m_width, width, height, width ) + left;
00081 luPixel down = calcSize( context, m_depthType, m_depthRelative, m_depth, width, height, depth );
00082 luPixel up = calcSize( context, m_heightType, m_heightRelative, m_height, width, height, height );
00083
00084
00085 if ( right < 0 ) right = 0;
00086 if ( up + down < 0 ) up = down = 0;
00087
00088 if ( ! isEmpty() ) {
00089 width = left;
00090
00091 for ( iterator it = begin(); it != end(); ++it ) {
00092 luPixel spaceBefore = 0;
00093 if ( it == begin() ) {
00094 spaceBefore = context.ptToPixelX( getSpaceBefore( context, tstyle, factor ) );
00095 }
00096 it->calcSizes( context, tstyle, istyle, style );
00097 it->setX( width + spaceBefore );
00098 width += it->getWidth() + spaceBefore;
00099 }
00100
00101 setWidth( right );
00102 setHeight( up + down );
00103 setBaseline( up );
00104 setChildrenPositions();
00105 }
00106 else {
00107 setWidth( right );
00108 setHeight( up + down );
00109 setBaseline( up );
00110 }
00111 }
00112
00113 bool PaddedElement::readAttributesFromMathMLDom(const QDomElement& element)
00114 {
00115 if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) {
00116 return false;
00117 }
00118
00119 QString widthStr = element.attribute( "width" ).stripWhiteSpace().lower();
00120 if ( ! widthStr.isNull() ) {
00121 m_width = readSizeAttribute( widthStr, &m_widthType, &m_widthRelative );
00122 }
00123 QString lspaceStr = element.attribute( "lspace" ).stripWhiteSpace().lower();
00124 if ( ! lspaceStr.isNull() ) {
00125 m_lspace = readSizeAttribute( lspaceStr, &m_lspaceType, &m_lspaceRelative );
00126 }
00127 QString heightStr = element.attribute( "height" ).stripWhiteSpace().lower();
00128 if ( ! heightStr.isNull() ) {
00129 m_height = readSizeAttribute( heightStr, &m_heightType, &m_heightRelative );
00130 }
00131 QString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower();
00132 if ( ! depthStr.isNull() ) {
00133 m_depth = readSizeAttribute( depthStr, &m_depthType, &m_depthRelative );
00134 }
00135
00136 return true;
00137 }
00138
00139 void PaddedElement::writeMathMLAttributes( QDomElement& element ) const
00140 {
00141 writeSizeAttribute( element, "width", m_widthType, m_width, m_widthRelative );
00142 writeSizeAttribute( element, "lspace", m_lspaceType, m_lspace, m_lspaceRelative );
00143 writeSizeAttribute( element, "height", m_heightType, m_height, m_heightRelative );
00144 writeSizeAttribute( element, "depth", m_depthType, m_depth, m_depthRelative );
00145 }
00146
00147 double PaddedElement::readSizeAttribute( const QString& str, SizeType* st, bool* relative )
00148 {
00149 if ( st == 0 ){
00150 return -1;
00151 }
00152 if ( str[0] == '+' || str[0] == '-' ) {
00153 *relative = true;
00154 }
00155 int index = str.find( "width" );
00156 if ( index != -1 ) {
00157 int index2 = str.find( "%" );
00158 if ( index2 != -1 ) {
00159 return str2size( str.left( index2 ).stripWhiteSpace(), st, WidthRelativeSize ) / 100.0;
00160 }
00161 return str2size( str.left( index ).stripWhiteSpace(), st, WidthRelativeSize );
00162 }
00163 index = str.find( "height" );
00164 if ( index != -1 ) {
00165 int index2 = str.find( "%" );
00166 if ( index2 != -1 ) {
00167 return str2size( str.left( index2 ).stripWhiteSpace(), st, HeightRelativeSize ) / 100.0;
00168 }
00169 return str2size( str.left( index ).stripWhiteSpace(), st, HeightRelativeSize );
00170 }
00171 index = str.find( "%" );
00172 if ( index != -1 ) {
00173 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize ) / 100.0;
00174 }
00175 index = str.find( "pt", 0, false );
00176 if ( index != -1 ) {
00177 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize );
00178 }
00179 index = str.find( "mm", 0, false );
00180 if ( index != -1 ) {
00181 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 20.54;
00182 }
00183 index = str.find( "cm", 0, false );
00184 if ( index != -1 ) {
00185 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0 / 2.54;
00186 }
00187 index = str.find( "in", 0, false );
00188 if ( index != -1 ) {
00189 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 72.0;
00190 }
00191 index = str.find( "em", 0, false );
00192 if ( index != -1 ) {
00193 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
00194 }
00195 index = str.find( "ex", 0, false );
00196 if ( index != -1 ) {
00197 return str2size( str.left( index ).stripWhiteSpace(), st, RelativeSize );
00198 }
00199 index = str.find( "pc", 0, false );
00200 if ( index != -1 ) {
00201 return str2size( str.left( index ).stripWhiteSpace(), st, AbsoluteSize ) * 12.0;
00202 }
00203 index = str.find( "px", 0, false );
00204 if ( index != -1 ) {
00205 return str2size( str.left( index ).stripWhiteSpace(), st, PixelSize );
00206 }
00207
00208 return str2size( str, st, AbsoluteSize );
00209 }
00210
00211 double PaddedElement::str2size( const QString& str, SizeType *st, SizeType type )
00212 {
00213 bool ok;
00214 double size = str.toDouble( &ok );
00215 if ( ok ) {
00216 if ( st ) {
00217 *st = type;
00218 }
00219 return size;
00220 }
00221 if ( st ) {
00222 *st = NoSize;
00223 }
00224 return -1;
00225 }
00226
00227 void PaddedElement::writeSizeAttribute( QDomElement element, const QString& str,
00228 SizeType st, bool relative, double s ) const
00229 {
00230 QString prefix;
00231 if ( relative ) {
00232 s < 0 ? prefix = "-" : prefix = "+" ;
00233 }
00234 switch ( st ) {
00235 case WidthRelativeSize:
00236 element.setAttribute( str, prefix + QString( "%1 width" ).arg( s ) );
00237 break;
00238 case HeightRelativeSize:
00239 element.setAttribute( str, prefix + QString( "%1 height" ).arg( s ) );
00240 case AbsoluteSize:
00241 element.setAttribute( str, prefix + QString( "%1pt" ).arg( s ) );
00242 break;
00243 case RelativeSize:
00244 element.setAttribute( str, prefix + QString( "%1%" ).arg( s * 100.0 ) );
00245 break;
00246 case PixelSize:
00247 element.setAttribute( str, prefix + QString( "%1px" ).arg( s ) );
00248 break;
00249 default:
00250 break;
00251 }
00252 }
00253
00254 luPixel PaddedElement::calcSize( const ContextStyle& context, SizeType type,
00255 bool relative, double length, luPixel width,
00256 luPixel height, luPixel defvalue )
00257 {
00258 luPixel value = defvalue;
00259 switch ( type ) {
00260 case AbsoluteSize:
00261 if ( relative )
00262 value += context.ptToLayoutUnitPt ( length );
00263 else
00264 value = context.ptToLayoutUnitPt( length );
00265 break;
00266 case RelativeSize:
00267 if ( relative )
00268 value += length * value;
00269 else
00270 value *= length;
00271 break;
00272 case WidthRelativeSize:
00273 if ( relative )
00274 value += length * width;
00275 else
00276 value = length * width;
00277 break;
00278 case HeightRelativeSize:
00279 if ( relative )
00280 value += length * height;
00281 else
00282 value = length * height;
00283 break;
00284 case PixelSize:
00285 if ( relative )
00286 value += context.pixelToLayoutUnitX( length );
00287 else
00288 value = context.pixelToLayoutUnitX( length );
00289 break;
00290 default:
00291 break;
00292 }
00293 return value;
00294 }
00295
00296 KFORMULA_NAMESPACE_END