00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qpainter.h>
00021
00022 #include "basicelement.h"
00023 #include "tokenstyleelement.h"
00024
00025 KFORMULA_NAMESPACE_BEGIN
00026
00027 TokenStyleElement::TokenStyleElement( BasicElement* parent ) : SequenceElement( parent ),
00028 m_mathSizeType ( NoSize ),
00029 m_charStyle( anyChar ),
00030 m_charFamily( anyFamily ),
00031 m_mathColor( "#000000" ),
00032 m_mathBackground( "#FFFFFF" ),
00033 m_fontSizeType( NoSize ),
00034 m_customMathVariant( false ),
00035 m_customMathColor( false ),
00036 m_customMathBackground( false ),
00037 m_customFontWeight( false ),
00038 m_customFontStyle( false ),
00039 m_customFontFamily( false ),
00040 m_customColor( false )
00041 {
00042 }
00043
00044 void TokenStyleElement::calcSizes( const ContextStyle& context,
00045 ContextStyle::TextStyle tstyle,
00046 ContextStyle::IndexStyle istyle,
00047 StyleAttributes& style )
00048 {
00049 setStyleSize( context, style );
00050 setStyleVariant( style );
00051 setStyleColor( style );
00052 setStyleBackground( style );
00053 inherited::calcSizes( context, tstyle, istyle, style );
00054 resetStyle( style );
00055 }
00056
00057 void TokenStyleElement::draw( QPainter& painter, const LuPixelRect& r,
00058 const ContextStyle& context,
00059 ContextStyle::TextStyle tstyle,
00060 ContextStyle::IndexStyle istyle,
00061 StyleAttributes& style,
00062 const LuPixelPoint& parentOrigin )
00063 {
00064 setStyleSize( context, style );
00065 setStyleVariant( style );
00066 setStyleColor( style );
00067 setStyleBackground( style );
00068 if ( style.background() != Qt::color0 ) {
00069 painter.fillRect( context.layoutUnitToPixelX( parentOrigin.x() + getX() ),
00070 context.layoutUnitToPixelY( parentOrigin.y() + getY() ),
00071 context.layoutUnitToPixelX( getWidth() ),
00072 context.layoutUnitToPixelY( getHeight() ),
00073 style.background() );
00074 }
00075 inherited::draw( painter, r, context, tstyle, istyle, style, parentOrigin );
00076 resetStyle( style );
00077 }
00078
00079 bool TokenStyleElement::readAttributesFromMathMLDom( const QDomElement& element )
00080 {
00081 if ( !BasicElement::readAttributesFromMathMLDom( element ) ) {
00082 return false;
00083 }
00084
00085
00086 QString variantStr = element.attribute( "mathvariant" );
00087 if ( !variantStr.isNull() ) {
00088 if ( variantStr == "normal" ) {
00089 setCharStyle( normalChar );
00090 setCharFamily( normalFamily );
00091 }
00092 else if ( variantStr == "bold" ) {
00093 setCharStyle( boldChar );
00094 setCharFamily( normalFamily );
00095 }
00096 else if ( variantStr == "italic" ) {
00097 setCharStyle( italicChar );
00098 setCharFamily( normalFamily );
00099 }
00100 else if ( variantStr == "bold-italic" ) {
00101 setCharStyle( boldItalicChar );
00102 setCharFamily( normalFamily );
00103 }
00104 else if ( variantStr == "double-struck" ) {
00105 setCharStyle( normalChar );
00106 setCharFamily( doubleStruckFamily );
00107 }
00108 else if ( variantStr == "bold-fraktur" ) {
00109 setCharStyle( boldChar );
00110 setCharFamily( frakturFamily );
00111 }
00112 else if ( variantStr == "script" ) {
00113 setCharStyle( normalChar );
00114 setCharFamily( scriptFamily );
00115 }
00116 else if ( variantStr == "bold-script" ) {
00117 setCharStyle( boldChar );
00118 setCharFamily( scriptFamily );
00119 }
00120 else if ( variantStr == "fraktur" ) {
00121 setCharStyle( boldChar );
00122 setCharFamily( frakturFamily );
00123 }
00124 else if ( variantStr == "sans-serif" ) {
00125 setCharStyle( normalChar );
00126 setCharFamily( sansSerifFamily );
00127 }
00128 else if ( variantStr == "bold-sans-serif" ) {
00129 setCharStyle( boldChar );
00130 setCharFamily( sansSerifFamily );
00131 }
00132 else if ( variantStr == "sans-serif-italic" ) {
00133 setCharStyle( italicChar );
00134 setCharFamily( sansSerifFamily );
00135 }
00136 else if ( variantStr == "sans-serif-bold-italic" ) {
00137 setCharStyle( boldItalicChar );
00138 setCharFamily( sansSerifFamily );
00139 }
00140 else if ( variantStr == "monospace" ) {
00141 setCharStyle( normalChar );
00142 setCharFamily( monospaceFamily );
00143 }
00144 }
00145
00146 QString sizeStr = element.attribute( "mathsize" );
00147 if ( !sizeStr.isNull() ) {
00148 if ( sizeStr == "small" ) {
00149 setRelativeSize( 0.8 );
00150 }
00151 else if ( sizeStr == "normal" ) {
00152 setRelativeSize( 1.0 );
00153 }
00154 else if ( sizeStr == "big" ) {
00155 setRelativeSize( 1.2 );
00156 }
00157 else {
00158 double s = getSize( sizeStr, &m_mathSizeType );
00159 switch ( m_mathSizeType ) {
00160 case AbsoluteSize:
00161 setAbsoluteSize( s );
00162 break;
00163 case RelativeSize:
00164 setRelativeSize( s );
00165 break;
00166 case PixelSize:
00167 setPixelSize( s );
00168 break;
00169 default:
00170 break;
00171 }
00172 }
00173 }
00174
00175 QString colorStr = element.attribute( "mathcolor" );
00176 if ( !colorStr.isNull() ) {
00177 if ( colorStr[0] != '#' ) {
00178 setMathColor( QColor( getHtmlColor( colorStr ) ) );
00179 }
00180 else {
00181 setMathColor( QColor( colorStr ) );
00182 }
00183 }
00184 QString backgroundStr = element.attribute( "mathbackground" );
00185 if ( !backgroundStr.isNull() ) {
00186 if ( backgroundStr[0] != '#' ) {
00187 setMathBackground( QColor( getHtmlColor( backgroundStr ) ) );
00188 }
00189 else {
00190 setMathBackground( QColor( backgroundStr ) );
00191 }
00192 }
00193
00194
00195
00196 sizeStr = element.attribute( "fontsize" );
00197 if ( ! sizeStr.isNull() ) {
00198 if ( sizeStr == "small" ) {
00199 setRelativeSize( 0.8, true );
00200 }
00201 else if ( sizeStr == "normal" ) {
00202 setRelativeSize( 1.0, true );
00203 }
00204 else if ( sizeStr == "big" ) {
00205 setRelativeSize( 1.2, true );
00206 }
00207 else {
00208 double s = getSize( sizeStr, &m_fontSizeType );
00209 switch ( m_fontSizeType ) {
00210 case AbsoluteSize:
00211 setAbsoluteSize( s, true );
00212 break;
00213 case RelativeSize:
00214 setRelativeSize( s, true );
00215 break;
00216 case PixelSize:
00217 setPixelSize( s, true );
00218 break;
00219 default:
00220 break;
00221 }
00222 }
00223 }
00224
00225 QString styleStr = element.attribute( "fontstyle" );
00226 if ( ! styleStr.isNull() ) {
00227 if ( styleStr.lower() == "italic" ) {
00228 setFontStyle( true );
00229 }
00230 else {
00231 setFontStyle( false );
00232 }
00233 }
00234
00235 QString weightStr = element.attribute( "fontweight" );
00236 if ( ! weightStr.isNull() ) {
00237 if ( weightStr.lower() == "bold" ) {
00238 setFontWeight( true );
00239 }
00240 else {
00241 setFontWeight( false );
00242 }
00243 }
00244
00245 QString familyStr = element.attribute( "fontfamily" );
00246 if ( ! familyStr.isNull() ) {
00247 setFontFamily( familyStr );
00248 }
00249
00250 colorStr = element.attribute( "color" );
00251 if ( ! colorStr.isNull() ) {
00252 if ( colorStr[0] != '#' ) {
00253 setColor( QColor( getHtmlColor( colorStr ) ) );
00254 }
00255 else {
00256 setColor( QColor( colorStr ) );
00257 }
00258 }
00259
00260 return true;
00261 }
00262
00263 void TokenStyleElement::writeMathMLAttributes( QDomElement& element ) const
00264 {
00265
00266 if ( customMathVariant() ) {
00267 if ( charFamily() == normalFamily ) {
00268 if ( charStyle() == normalChar ) {
00269 element.setAttribute( "mathvariant", "normal" );
00270 }
00271 else if ( charStyle() == boldChar ) {
00272 element.setAttribute( "mathvariant", "bold" );
00273 }
00274 else if ( charStyle() == italicChar ) {
00275 element.setAttribute( "mathvariant", "italic" );
00276 }
00277 else if ( charStyle() == boldItalicChar ) {
00278 element.setAttribute( "mathvariant", "bold-italic" );
00279 }
00280 else {
00281 kdWarning( DEBUGID ) << "Mathvariant: unknown style for normal family\n";
00282 }
00283 }
00284 else if ( charFamily() == doubleStruckFamily ) {
00285 if ( charStyle() == normalChar ) {
00286 element.setAttribute( "mathvariant", "double-struck" );
00287 }
00288 else {
00289 kdWarning( DEBUGID ) << "Mathvariant: unknown style for double-struck family\n";
00290 }
00291 }
00292 else if ( charFamily() == frakturFamily ) {
00293 if ( charStyle() == normalChar ) {
00294 element.setAttribute( "mathvariant", "fraktur" );
00295 }
00296 else if ( charStyle() == boldChar ) {
00297 element.setAttribute( "mathvariant", "bold-fraktur" );
00298 }
00299 else {
00300 kdWarning( DEBUGID ) << "Mathvariant: unknown style for fraktur family\n";
00301 }
00302 }
00303 else if ( charFamily() == scriptFamily ) {
00304 if ( charStyle() == normalChar ) {
00305 element.setAttribute( "mathvariant", "script" );
00306 }
00307 else if ( charStyle() == boldChar ) {
00308 element.setAttribute( "mathvariant", "bold-script" );
00309 }
00310 else {
00311 kdWarning( DEBUGID ) << "Mathvariant: unknown style for script family\n";
00312 }
00313 }
00314 else if ( charFamily() == sansSerifFamily ) {
00315 if ( charStyle() == normalChar ) {
00316 element.setAttribute( "mathvariant", "sans-serif" );
00317 }
00318 else if ( charStyle() == boldChar ) {
00319 element.setAttribute( "mathvariant", "bold-sans-serif" );
00320 }
00321 else if ( charStyle() == italicChar ) {
00322 element.setAttribute( "mathvariant", "sans-serif-italic" );
00323 }
00324 else if ( charStyle() == boldItalicChar ) {
00325 element.setAttribute( "mathvariant", "sans-serif-bold-italic" );
00326 }
00327 else {
00328 kdWarning( DEBUGID ) << "Mathvariant: unknown style for sans serif family\n";
00329 }
00330 }
00331 else if ( charFamily() == monospaceFamily ) {
00332 if ( charStyle() == normalChar ) {
00333 element.setAttribute( "mathvariant", "monospace" );
00334 }
00335 else {
00336 kdWarning( DEBUGID ) << "Mathvariant: unknown style for monospace family\n";
00337 }
00338 }
00339 else {
00340 kdWarning( DEBUGID ) << "Mathvariant: unknown family\n";
00341 }
00342 }
00343
00344
00345 switch ( m_mathSizeType ) {
00346 case AbsoluteSize:
00347 element.setAttribute( "mathsize", QString( "%1pt" ).arg( m_mathSize ) );
00348 break;
00349 case RelativeSize:
00350 element.setAttribute( "mathsize", QString( "%1%" ).arg( m_mathSize * 100.0 ) );
00351 break;
00352 case PixelSize:
00353 element.setAttribute( "mathsize", QString( "%1px" ).arg( m_mathSize ) );
00354 break;
00355 default:
00356 break;
00357 }
00358
00359
00360 if ( customMathColor() ) {
00361 element.setAttribute( "mathcolor", mathColor().name() );
00362 }
00363
00364
00365 if ( customMathBackground() ) {
00366 element.setAttribute( "mathbackground", mathBackground().name() );
00367 }
00368
00369
00370
00371 switch ( m_fontSizeType ) {
00372 case AbsoluteSize:
00373 element.setAttribute( "fontsize", QString( "%1pt" ).arg( m_fontSize ) );
00374 break;
00375 case RelativeSize:
00376 element.setAttribute( "fontsize", QString( "%1%" ).arg( m_fontSize * 100.0 ) );
00377 break;
00378 case PixelSize:
00379 element.setAttribute( "fontsize", QString( "%3px" ).arg( m_fontSize ) );
00380 break;
00381 default:
00382 break;
00383 }
00384
00385
00386 if ( customFontWeight() ) {
00387 element.setAttribute( "fontweight", fontWeight() ? "bold" : "normal" );
00388 }
00389
00390
00391 if ( customFontStyle() ) {
00392 element.setAttribute( "fontstyle", fontStyle() ? "italic" : "normal" );
00393 }
00394
00395
00396 if ( customFontFamily() ) {
00397 element.setAttribute( "fontfamily", fontFamily() );
00398 }
00399
00400
00401 if ( customColor() ) {
00402 element.setAttribute( "color", color().name() );
00403 }
00404 }
00405
00406 void TokenStyleElement::setAbsoluteSize( double s, bool fontsize )
00407 {
00408 kdDebug( DEBUGID) << "Setting absolute size: " << s << endl;
00409 if ( fontsize ) {
00410 m_fontSizeType = AbsoluteSize;
00411 m_fontSize = s;
00412 }
00413 else {
00414 m_mathSizeType = AbsoluteSize;
00415 m_mathSize = s;
00416 }
00417 }
00418
00419 void TokenStyleElement::setRelativeSize( double f, bool fontsize )
00420 {
00421 kdDebug( DEBUGID) << "Setting relative size: " << f << endl;
00422 if ( fontsize ) {
00423 m_fontSizeType = RelativeSize;
00424 m_fontSize = f;
00425 }
00426 else {
00427 m_mathSizeType = RelativeSize;
00428 m_mathSize = f;
00429 }
00430 }
00431
00432 void TokenStyleElement::setPixelSize( double px, bool fontsize )
00433 {
00434 kdDebug( DEBUGID) << "Setting pixel size: " << px << endl;
00435 if ( fontsize ) {
00436 m_fontSizeType = PixelSize;
00437 m_fontSize = px;
00438 }
00439 else {
00440 m_mathSizeType = PixelSize;
00441 m_mathSize = px;
00442 }
00443 }
00444
00445 void TokenStyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style )
00446 {
00447 style.setSizeFactor( sizeFactor( context, style.sizeFactor() ) );
00448 }
00449
00450 void TokenStyleElement::setStyleVariant( StyleAttributes& style )
00451 {
00452 if ( customMathVariant() || style.customMathVariant() ) {
00453 style.setCustomMathVariant ( true );
00454 style.setCustomFontWeight( false );
00455 style.setCustomFontStyle( false );
00456 style.setCustomFont( false );
00457 if ( customMathVariant() ) {
00458 style.setCharFamily ( charFamily() );
00459 style.setCharStyle( charStyle() );
00460 }
00461 else {
00462 style.setCharFamily( style.charFamily() );
00463 style.setCharStyle( style.charStyle() );
00464 }
00465 }
00466 else {
00467 style.setCustomMathVariant( false );
00468 if ( customFontFamily() ) {
00469 style.setCustomFont( true );
00470 style.setFont( QFont(fontFamily()) );
00471 }
00472
00473 bool fontweight = false;
00474 if ( customFontWeight() || style.customFontWeight() ) {
00475 style.setCustomFontWeight( true );
00476 if ( customFontWeight() ) {
00477 fontweight = fontWeight();
00478 }
00479 else {
00480 fontweight = style.fontWeight();
00481 }
00482 style.setFontWeight( fontweight );
00483 }
00484 else {
00485 style.setCustomFontWeight( false );
00486 }
00487
00488 bool fontstyle = false;
00489 if ( style.customFontStyle() ) {
00490 style.setCustomFontStyle( true );
00491 fontstyle = style.fontStyle();
00492 style.setFontStyle( fontstyle );
00493 }
00494 else {
00495 style.setCustomFontStyle( false );
00496 }
00497 if ( customFontStyle() ) {
00498 fontstyle = fontStyle();
00499 }
00500
00501 if ( fontweight && fontstyle ) {
00502 style.setCharStyle( boldItalicChar );
00503 }
00504 else if ( fontweight && ! fontstyle ) {
00505 style.setCharStyle( boldChar );
00506 }
00507 else if ( ! fontweight && fontstyle ) {
00508 style.setCharStyle( italicChar );
00509 }
00510 else {
00511 style.setCharStyle( normalChar );
00512 }
00513 }
00514 }
00515
00516 void TokenStyleElement::setStyleColor( StyleAttributes& style )
00517 {
00518 if ( customMathColor() ) {
00519 style.setColor( mathColor() );
00520 }
00521 else if ( customColor() ) {
00522 style.setColor( color() );
00523 }
00524 else {
00525 style.setColor( style.color() );
00526 }
00527 }
00528
00529 void TokenStyleElement::setStyleBackground( StyleAttributes& style )
00530 {
00531 if ( customMathBackground() ) {
00532 style.setBackground( mathBackground() );
00533 }
00534 else {
00535 style.setBackground( style.background() );
00536 }
00537 }
00538
00539 void TokenStyleElement::resetStyle( StyleAttributes& style )
00540 {
00541 style.resetSize();
00542 style.resetCharStyle();
00543 style.resetCharFamily();
00544 style.resetColor();
00545 style.resetBackground();
00546 style.resetFontFamily();
00547 style.resetFontWeight();
00548 style.resetFontStyle();
00549 }
00550
00551 double TokenStyleElement::sizeFactor( const ContextStyle& context, double factor )
00552 {
00553 double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
00554 switch ( m_mathSizeType ) {
00555 case AbsoluteSize:
00556 return m_mathSize / basesize;
00557 case RelativeSize:
00558 return m_mathSize;
00559 case PixelSize:
00560
00561 return context.pixelYToPt( m_mathSize ) / basesize;
00562 case NoSize:
00563 switch ( m_fontSizeType ) {
00564 case AbsoluteSize:
00565 return m_fontSize / basesize;
00566 case RelativeSize:
00567 return m_fontSize;
00568 case PixelSize:
00569 return context.pixelYToPt( m_fontSize ) / basesize;
00570 default:
00571 return factor;
00572 }
00573 default:
00574 break;
00575 }
00576 kdWarning( DEBUGID ) << k_funcinfo << " Unknown SizeType\n";
00577 return factor;
00578 }
00579
00583 QString TokenStyleElement::getHtmlColor( const QString& colorStr ){
00584
00585 QString colorname = colorStr.lower();
00586
00587 if ( colorname == "black" )
00588 return "#000000";
00589 if ( colorname == "silver" )
00590 return "#C0C0C0";
00591 if ( colorname == "gray" )
00592 return "#808080";
00593 if ( colorname == "white" )
00594 return "#FFFFFF";
00595 if ( colorname == "maroon" )
00596 return "#800000";
00597 if ( colorname == "red" )
00598 return "#FF0000";
00599 if ( colorname == "purple" )
00600 return "#800080";
00601 if ( colorname == "fuchsia" )
00602 return "#FF00FF";
00603 if ( colorname == "green" )
00604 return "#008000";
00605 if ( colorname == "lime" )
00606 return "#00FF00";
00607 if ( colorname == "olive" )
00608 return "#808000";
00609 if ( colorname == "yellow" )
00610 return "#FFFF00";
00611 if ( colorname == "navy" )
00612 return "#000080";
00613 if ( colorname == "blue")
00614 return "#0000FF";
00615 if ( colorname == "teal" )
00616 return "#008080";
00617 if ( colorname == "aqua" )
00618 return "#00FFFF";
00619 kdWarning( DEBUGID ) << "Invalid HTML color: " << colorname << endl;
00620 return "#FFFFFF";
00621 }
00622
00623
00624 KFORMULA_NAMESPACE_END