00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "basicelement.h"
00021 #include "styleelement.h"
00022
00023 KFORMULA_NAMESPACE_BEGIN
00024
00025 StyleElement::StyleElement( BasicElement* parent ) : TokenStyleElement( parent ),
00026 m_scriptMinSizeType( NoSize ),
00027 m_veryVeryThinMathSpaceType( NoSize ),
00028 m_veryThinMathSpaceType( NoSize ),
00029 m_thinMathSpaceType( NoSize ),
00030 m_mediumMathSpaceType( NoSize ),
00031 m_thickMathSpaceType( NoSize ),
00032 m_veryThickMathSpaceType( NoSize ),
00033 m_veryVeryThickMathSpaceType( NoSize ),
00034 m_customScriptLevel( false ),
00035 m_relativeScriptLevel( false ),
00036 m_customDisplayStyle( false ),
00037 m_customScriptSizeMultiplier( false ),
00038 m_customBackground( false )
00039 {
00040 }
00041
00042 bool StyleElement::readAttributesFromMathMLDom( const QDomElement& element )
00043 {
00044 if ( !BasicElement::readAttributesFromMathMLDom( element ) ) {
00045 return false;
00046 }
00047
00048 QString scriptlevelStr = element.attribute( "scriptlevel" );
00049 if ( ! scriptlevelStr.isNull() ) {
00050 if ( scriptlevelStr[0] == '+' || scriptlevelStr[0] == '-' ) {
00051 m_relativeScriptLevel = true;
00052 }
00053 bool ok;
00054 m_scriptLevel = scriptlevelStr.toInt( &ok );
00055 if ( ! ok ) {
00056 kdWarning( DEBUGID ) << "Invalid scriptlevel attribute value: "
00057 << scriptlevelStr << endl;
00058 }
00059 else {
00060 m_customScriptLevel = true;
00061 }
00062 }
00063 QString displaystyleStr = element.attribute( "displaystyle" );
00064 if ( ! displaystyleStr.isNull() ) {
00065 if ( displaystyleStr.lower() == "true" ) {
00066 m_displayStyle = true;
00067 }
00068 else {
00069 m_displayStyle = false;
00070 }
00071 m_customDisplayStyle = true;
00072 }
00073 QString scriptsizemultiplierStr = element.attribute( "scriptsizemultiplier" );
00074 if ( ! scriptsizemultiplierStr.isNull() ) {
00075 bool ok;
00076 m_scriptSizeMultiplier = scriptsizemultiplierStr.toDouble( &ok );
00077 if ( ! ok ) {
00078 kdWarning( DEBUGID ) << "Invalid scriptsizemultiplier attribute value: "
00079 << scriptsizemultiplierStr << endl;
00080 }
00081 else {
00082 m_customScriptSizeMultiplier = true;
00083 }
00084 }
00085 QString scriptminsizeStr = element.attribute( "scriptminsize" );
00086 if ( ! scriptminsizeStr.isNull() ) {
00087 readSizeAttribute( scriptminsizeStr, &m_scriptMinSizeType, &m_scriptMinSize );
00088 }
00089 QString backgroundStr = element.attribute( "background" );
00090 if ( ! backgroundStr.isNull() ) {
00091
00092 m_customBackground = true;
00093 if ( backgroundStr[0] != '#' ) {
00094 m_background = QColor( getHtmlColor( backgroundStr ) );
00095 }
00096 else {
00097 m_background = QColor( backgroundStr );
00098 }
00099 }
00100 QString veryverythinmathspaceStr = element.attribute( "veryverythinmathspace" );
00101 if ( ! veryverythinmathspaceStr.isNull() ) {
00102 readSizeAttribute( veryverythinmathspaceStr, &m_veryVeryThinMathSpaceType, &m_veryVeryThinMathSpace );
00103 }
00104 QString verythinmathspaceStr = element.attribute( "verythinmathspace" );
00105 if ( ! verythinmathspaceStr.isNull() ) {
00106 readSizeAttribute( verythinmathspaceStr, &m_veryThinMathSpaceType, &m_veryThinMathSpace );
00107 }
00108 QString thinmathspaceStr = element.attribute( "thinmathspace" );
00109 if ( ! thinmathspaceStr.isNull() ) {
00110 readSizeAttribute( thinmathspaceStr, &m_thinMathSpaceType, &m_thinMathSpace );
00111 }
00112 QString mediummathspaceStr = element.attribute( "mediummathspace" );
00113 if ( ! mediummathspaceStr.isNull() ) {
00114 readSizeAttribute( mediummathspaceStr, &m_mediumMathSpaceType, &m_mediumMathSpace );
00115 }
00116 QString thickmathspaceStr = element.attribute( "thickmathspace" );
00117 if ( ! thickmathspaceStr.isNull() ) {
00118 readSizeAttribute( thickmathspaceStr, &m_thickMathSpaceType, &m_thickMathSpace );
00119 }
00120 QString verythickmathspaceStr = element.attribute( "verythickmathspace" );
00121 if ( ! verythickmathspaceStr.isNull() ) {
00122 readSizeAttribute( verythickmathspaceStr, &m_veryThickMathSpaceType, &m_veryThickMathSpace );
00123 }
00124 QString veryverythickmathspaceStr = element.attribute( "veryverythickmathspace" );
00125 if ( ! veryverythickmathspaceStr.isNull() ) {
00126 readSizeAttribute( veryverythickmathspaceStr, &m_veryVeryThickMathSpaceType, &m_veryVeryThickMathSpace );
00127 }
00128 return inherited::readAttributesFromMathMLDom( element );
00129 }
00130
00131 void StyleElement::writeMathMLAttributes( QDomElement& element ) const
00132 {
00133 if ( m_customScriptLevel ) {
00134 QString prefix;
00135 if ( m_relativeScriptLevel && m_scriptLevel >= 0 ) {
00136 prefix = "+";
00137 }
00138 element.setAttribute( "scriptlevel", prefix + QString( "%1" ).arg( m_scriptLevel ) );
00139 }
00140 if ( m_customDisplayStyle ) {
00141 element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" );
00142 }
00143 if ( m_customScriptSizeMultiplier ) {
00144 element.setAttribute( "scriptsizemultiplier", QString( "%1" ).arg( m_scriptSizeMultiplier ) );
00145 }
00146 writeSizeAttribute( element, "scriptminsize", m_scriptMinSizeType, m_scriptMinSize );
00147 if ( m_customBackground ) {
00148 element.setAttribute( "background", m_background.name() );
00149 }
00150 writeSizeAttribute( element, "veryverythinmathspace", m_veryVeryThinMathSpaceType, m_veryVeryThinMathSpace );
00151 writeSizeAttribute( element, "verythinmathspace", m_veryThinMathSpaceType, m_veryThinMathSpace );
00152 writeSizeAttribute( element, "thinmathspace", m_thinMathSpaceType, m_thinMathSpace );
00153 writeSizeAttribute( element, "mediummathspace", m_mediumMathSpaceType, m_mediumMathSpace );
00154 writeSizeAttribute( element, "thickmathspace", m_thickMathSpaceType, m_thickMathSpace );
00155 writeSizeAttribute( element, "verythickmathspace", m_veryThickMathSpaceType, m_veryThickMathSpace );
00156 writeSizeAttribute( element, "veryverythickmathspace", m_veryVeryThickMathSpaceType, m_veryVeryThickMathSpace );
00157
00158 inherited::writeMathMLAttributes( element );
00159 }
00160
00161
00162 void StyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style )
00163 {
00164 if ( m_customScriptLevel ) {
00165 if ( m_relativeScriptLevel ) {
00166 style.setScriptLevel( style.scriptLevel() + m_scriptLevel );
00167 }
00168 else {
00169 style.setScriptLevel( m_scriptLevel );
00170 }
00171 }
00172 else {
00173 style.setScriptLevel( style.scriptLevel() );
00174 }
00175 if ( m_customDisplayStyle || style.customDisplayStyle() ) {
00176 style.setCustomDisplayStyle( true );
00177 if ( m_customDisplayStyle ) {
00178 style.setDisplayStyle( m_displayStyle );
00179 }
00180 else {
00181 style.setDisplayStyle( style.displayStyle() );
00182 }
00183 }
00184 else {
00185 style.setCustomDisplayStyle( false );
00186 }
00187 if ( m_customScriptSizeMultiplier ) {
00188 style.setScriptSizeMultiplier( m_scriptSizeMultiplier );
00189 }
00190 else {
00191 style.setScriptSizeMultiplier( style.scriptSizeMultiplier() );
00192 }
00193
00194
00195
00196 double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
00197 double size = style.scriptMinSize();
00198 switch ( m_scriptMinSizeType ) {
00199 case AbsoluteSize:
00200 size = m_scriptMinSize;
00201 case RelativeSize:
00202 size = m_scriptMinSize * basesize;
00203 case PixelSize:
00204 size = context.pixelXToPt( m_scriptMinSize );
00205 default:
00206 break;
00207 }
00208 style.setScriptMinSize( size );
00209
00210 style.setVeryVeryThinMathSpace( sizeFactor( context,
00211 m_veryVeryThinMathSpaceType,
00212 m_veryVeryThinMathSpace,
00213 style.veryVeryThinMathSpace() ));
00214 style.setVeryThinMathSpace( sizeFactor( context, m_veryThinMathSpaceType,
00215 m_veryThinMathSpace,
00216 style.veryThinMathSpace() ));
00217 style.setThinMathSpace( sizeFactor( context, m_thinMathSpaceType,
00218 m_thinMathSpace,
00219 style.thinMathSpace() ));
00220 style.setMediumMathSpace( sizeFactor( context, m_mediumMathSpaceType,
00221 m_mediumMathSpace,
00222 style.mediumMathSpace() ));
00223 style.setThickMathSpace( sizeFactor( context, m_thickMathSpaceType,
00224 m_thickMathSpace,
00225 style.thickMathSpace() ));
00226 style.setVeryThickMathSpace( sizeFactor( context, m_veryThickMathSpaceType,
00227 m_veryThickMathSpace,
00228 style.veryThickMathSpace() ));
00229 style.setVeryVeryThickMathSpace( sizeFactor( context,
00230 m_veryVeryThickMathSpaceType,
00231 m_veryVeryThickMathSpace,
00232 style.veryVeryThickMathSpace() ));
00233 inherited::setStyleSize( context, style );
00234 }
00235
00236 double StyleElement::sizeFactor( const ContextStyle& context, SizeType st,
00237 double length, double defvalue )
00238 {
00239 double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
00240 switch ( st ) {
00241 case AbsoluteSize:
00242 return length / basesize;
00243 case RelativeSize:
00244 return length;
00245 case PixelSize:
00246 return context.pixelXToPt( length ) / basesize;
00247 default:
00248 break;
00249 }
00250 return defvalue;
00251 }
00252
00253 void StyleElement::setStyleVariant( StyleAttributes& style )
00254 {
00255 if ( customMathVariant() ) {
00256 style.setCustomMathVariant ( true );
00257 style.setCustomFontWeight( false );
00258 style.setCustomFontStyle( false );
00259 style.setCustomFont( false );
00260 if ( customMathVariant() ) {
00261 style.setCharFamily ( charFamily() );
00262 style.setCharStyle( charStyle() );
00263 }
00264 else {
00265 style.setCharFamily( style.charFamily() );
00266 style.setCharStyle( style.charStyle() );
00267 }
00268 }
00269 else {
00270 style.setCustomMathVariant( false );
00271 if ( customFontFamily() ) {
00272 style.setCustomFont( true );
00273 style.setFont( QFont(fontFamily()) );
00274 }
00275
00276 bool fontweight = false;
00277 if ( customFontWeight() || style.customFontWeight() ) {
00278 style.setCustomFontWeight( true );
00279 if ( customFontWeight() ) {
00280 fontweight = fontWeight();
00281 }
00282 else {
00283 fontweight = style.fontWeight();
00284 }
00285 style.setFontWeight( fontweight );
00286 }
00287 else {
00288 style.setCustomFontWeight( false );
00289 }
00290
00291 bool fontstyle = false;
00292 if ( customFontStyle() || style.customFontStyle() ) {
00293 style.setCustomFontStyle( true );
00294 if ( customFontStyle() ) {
00295 fontstyle = fontStyle();
00296 }
00297 else {
00298 fontstyle = style.fontStyle();
00299 }
00300 style.setFontStyle( fontstyle );
00301 }
00302 else {
00303 style.setCustomFontStyle( false );
00304 }
00305
00306 if ( fontweight && fontstyle ) {
00307 style.setCharStyle( boldItalicChar );
00308 }
00309 else if ( fontweight && ! fontstyle ) {
00310 style.setCharStyle( boldChar );
00311 }
00312 else if ( ! fontweight && fontstyle ) {
00313 style.setCharStyle( italicChar );
00314 }
00315 else {
00316 style.setCharStyle( normalChar );
00317 }
00318 }
00319 }
00320
00321 void StyleElement::setStyleBackground( StyleAttributes& style )
00322 {
00323 if ( customMathBackground() ) {
00324 style.setBackground( mathBackground() );
00325 }
00326 else if ( m_customBackground ) {
00327 style.setBackground( m_background );
00328 }
00329 else {
00330 style.setBackground( style.background() );
00331 }
00332 }
00333
00334 void StyleElement::resetStyle( StyleAttributes& style )
00335 {
00336 inherited::resetStyle( style );
00337 style.resetScriptLevel();
00338 style.resetScriptSizeMultiplier();
00339 style.resetScriptMinSize();
00340 style.resetVeryVeryThinMathSpace();
00341 style.resetVeryThinMathSpace();
00342 style.resetThinMathSpace();
00343 style.resetMediumMathSpace();
00344 style.resetThickMathSpace();
00345 style.resetVeryThickMathSpace();
00346 style.resetVeryVeryThickMathSpace();
00347 style.resetDisplayStyle();
00348 }
00349
00350 void StyleElement::readSizeAttribute( const QString& str, SizeType* st, double* s )
00351 {
00352 if ( st == 0 || s == 0 ){
00353 return;
00354 }
00355 if ( str == "small" ) {
00356 *st = RelativeSize;
00357 *s = 0.8;
00358 }
00359 else if ( str == "normal" ) {
00360 *st = RelativeSize;
00361 *s = 1.0;
00362 }
00363 else if ( str == "big" ) {
00364 *st = RelativeSize;
00365 *s = 1.2;
00366 }
00367 else {
00368 *s = getSize( str, st );
00369 }
00370 }
00371
00372 void StyleElement::writeSizeAttribute( QDomElement element, const QString& str, SizeType st, double s ) const
00373 {
00374 switch ( st ) {
00375 case AbsoluteSize:
00376 element.setAttribute( str, QString( "%1pt" ).arg( s ) );
00377 break;
00378 case RelativeSize:
00379 element.setAttribute( str, QString( "%1%" ).arg( s * 100.0 ) );
00380 break;
00381 case PixelSize:
00382 element.setAttribute( str, QString( "%1px" ).arg( s ) );
00383 break;
00384 default:
00385 break;
00386 }
00387 }
00388
00389
00390 KFORMULA_NAMESPACE_END