00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <QFontMetrics>
00023 #include <QPaintDevice>
00024 #include <QString>
00025
00026 #include <kdebug.h>
00027 #include <KoGlobal.h>
00028
00029 #include "fontstyle.h"
00030 #include "contextstyle.h"
00031
00032
00033 KFORMULA_NAMESPACE_BEGIN
00034
00035
00036 ContextStyle::ContextStyle()
00037 : symbolFont( "Symbol" ),
00038 defaultColor(Qt::black), numberColor(Qt::blue),
00039 operatorColor(Qt::darkGreen), errorColor(Qt::darkRed),
00040 emptyColor(Qt::blue), helpColor( Qt::gray ), m_sizeFactor( 0 )
00041 {
00042 textStyleValues[ displayStyle ].setup( 1. );
00043 textStyleValues[ textStyle ].setup( 1. );
00044 textStyleValues[ scriptStyle ].setup( .7 );
00045 textStyleValues[ scriptScriptStyle ].setup( .49 );
00046
00047 m_baseTextStyle = displayStyle;
00048
00049 lineWidth = 1;
00050 linearMovement = false;
00051 centerSymbol = true;
00052 m_syntaxHighlighting = true;
00053
00054 m_fontStyle = 0;
00055 }
00056
00057
00058 ContextStyle::~ContextStyle()
00059 {
00060 delete m_fontStyle;
00061 }
00062
00063
00064 void ContextStyle::init( bool init )
00065 {
00066 setup();
00067 setFontStyle( m_fontStyleName, init );
00068 }
00069
00070
00071 void ContextStyle::setFontStyle( const QString& fontStyle, bool init )
00072 {
00073 delete m_fontStyle;
00074 m_fontStyleName = fontStyle;
00075 m_fontStyle = new FontStyle();
00076 m_fontStyle->init( this, init );
00077 }
00078
00079
00080 const SymbolTable& ContextStyle::symbolTable() const
00081 {
00082 return *( m_fontStyle->symbolTable() );
00083 }
00084
00085
00086 void ContextStyle::readConfig( KConfig* config, bool init )
00087 {
00088 config->setGroup( "kformula Font" );
00089 QString fontName = config->readEntry( "defaultFont", "Times,12,-1,5,50,1,0,0,0,0" );
00090 defaultFont.fromString( fontName );
00091 fontName = config->readEntry( "nameFont", "Times,12,-1,5,50,0,0,0,0,0" );
00092 nameFont.fromString( fontName );
00093 fontName = config->readEntry( "numberFont", "Times,12,-1,5,50,0,0,0,0,0" );
00094 numberFont.fromString( fontName );
00095 fontName = config->readEntry( "operatorFont", "Times,12,-1,5,50,0,0,0,0,0" );
00096 operatorFont.fromString( fontName );
00097 QString baseSize = config->readEntry( "baseSize", "20" );
00098 m_baseSize = baseSize.toInt();
00099
00100 if ( ! FontStyle::missingFonts( init ).isEmpty() ) {
00101 kdWarning( DEBUGID) << "Not all basic fonts found\n";
00102 }
00103 mathFont.fromString("Arev Sans");
00104 bracketFont.fromString("cmex10");
00105
00106
00107 config->setGroup( "kformula Color" );
00108 defaultColor = config->readEntry( "defaultColor", defaultColor );
00109 numberColor = config->readEntry( "numberColor", numberColor );
00110 operatorColor = config->readEntry( "operatorColor", operatorColor );
00111 emptyColor = config->readEntry( "emptyColor", emptyColor );
00112 errorColor = config->readEntry( "errorColor", errorColor );
00113 helpColor = config->readEntry( "helpColor", helpColor );
00114
00115 m_syntaxHighlighting = config->readEntry( "syntaxHighlighting", true );
00116 }
00117
00118 void ContextStyle::setZoomAndResolution( int zoom, int dpiX, int dpiY )
00119 {
00120 KoZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY );
00121 }
00122
00123 bool ContextStyle::setZoomAndResolution( int zoom, double zoomX, double zoomY, bool, bool )
00124 {
00125 bool changes = m_zoom != zoom || m_zoomedResolutionX != zoomX || m_zoomedResolutionY != zoomY;
00126 m_zoom = zoom;
00127 m_zoomedResolutionX = zoomX;
00128 m_zoomedResolutionY = zoomY;
00129 return changes;
00130 }
00131
00132 QColor ContextStyle::getNumberColor() const
00133 {
00134 if ( edit() && syntaxHighlighting() ) {
00135 return numberColor;
00136 }
00137 return getDefaultColor();
00138 }
00139
00140 QColor ContextStyle::getOperatorColor() const
00141 {
00142 if ( edit() && syntaxHighlighting() ) {
00143 return operatorColor;
00144 }
00145 return getDefaultColor();
00146 }
00147
00148 QColor ContextStyle::getErrorColor() const
00149 {
00150 if ( edit() && syntaxHighlighting() ) {
00151 return errorColor;
00152 }
00153 return getDefaultColor();
00154 }
00155
00156 QColor ContextStyle::getEmptyColor() const
00157 {
00158 if ( edit() && syntaxHighlighting() ) {
00159 return emptyColor;
00160 }
00161 return getDefaultColor();
00162 }
00163
00164 QColor ContextStyle::getHelpColor() const
00165 {
00166 if ( edit() && syntaxHighlighting() ) {
00167 return helpColor;
00168 }
00169 return getDefaultColor();
00170 }
00171
00172 void ContextStyle::setDefaultColor( const QColor& color )
00173 {
00174 defaultColor = color;
00175 }
00176 void ContextStyle::setNumberColor( const QColor& color )
00177 {
00178 numberColor = color;
00179 }
00180 void ContextStyle::setOperatorColor( const QColor& color )
00181 {
00182 operatorColor = color;
00183 }
00184 void ContextStyle::setErrorColor( const QColor& color )
00185 {
00186 errorColor = color;
00187 }
00188 void ContextStyle::setEmptyColor( const QColor& color )
00189 {
00190 emptyColor = color;
00191 }
00192 void ContextStyle::setHelpColor( const QColor& color )
00193 {
00194 helpColor = color;
00195 }
00196
00197 #if 0
00198 const QStringList& ContextStyle::requestedFonts() const
00199 {
00200 return m_requestedFonts;
00201 }
00202
00203 void ContextStyle::setRequestedFonts( const QStringList& list )
00204 {
00205 m_requestedFonts = list;
00206
00207 }
00208 #endif
00209
00210 double ContextStyle::getReductionFactor( TextStyle tstyle ) const
00211 {
00212 return textStyleValues[ tstyle ].reductionFactor;
00213 }
00214
00215 luPt ContextStyle::getAdjustedSize( TextStyle tstyle, double factor ) const
00216 {
00217 return ptToLayoutUnitPt( m_sizeFactor * m_baseSize
00218 * getReductionFactor( tstyle ) * factor );
00219 }
00220
00221 luPixel ContextStyle::getSpace( TextStyle tstyle, SpaceWidth space, double factor ) const
00222 {
00223 switch ( space ) {
00224 case NEGTHIN: return -getThinSpace( tstyle, factor );
00225 case THIN: return getThinSpace( tstyle, factor );
00226 case MEDIUM: return getMediumSpace( tstyle, factor );
00227 case THICK: return getThickSpace( tstyle, factor );
00228 case QUAD: return getQuadSpace( tstyle, factor );
00229 }
00230 return 0;
00231 }
00232
00233 luPixel ContextStyle::getThinSpace( TextStyle tstyle, double factor ) const
00234 {
00235 return ptToPixelX( m_sizeFactor
00236 * textStyleValues[ tstyle ].thinSpace( quad )
00237 * factor );
00238 }
00239
00240 luPixel ContextStyle::getMediumSpace( TextStyle tstyle, double factor ) const
00241 {
00242 return ptToPixelX( m_sizeFactor
00243 * textStyleValues[ tstyle ].mediumSpace( quad )
00244 * factor );
00245 }
00246
00247 luPixel ContextStyle::getThickSpace( TextStyle tstyle, double factor ) const
00248 {
00249 return ptToPixelX( m_sizeFactor
00250 * textStyleValues[ tstyle ].thickSpace( quad )
00251 * factor );
00252 }
00253
00254 luPixel ContextStyle::getQuadSpace( TextStyle tstyle, double factor ) const
00255 {
00256 return ptToPixelX( m_sizeFactor
00257 * textStyleValues[ tstyle ].quadSpace( quad )
00258 * factor );
00259 }
00260
00261 luPixel ContextStyle::axisHeight( TextStyle tstyle, double factor ) const
00262 {
00263
00264 return static_cast<luPixel>( m_sizeFactor
00265 * textStyleValues[ tstyle ].axisHeight( m_axisHeight )
00266 * factor );
00267 }
00268
00269 luPt ContextStyle::getBaseSize() const
00270 {
00271 return static_cast<luPt>( ptToLayoutUnitPt( m_sizeFactor*m_baseSize ) );
00272 }
00273
00274 void ContextStyle::setBaseSize( int size )
00275 {
00276
00277 if ( size != m_baseSize ) {
00278 m_baseSize = size;
00279 setup();
00280 }
00281 }
00282
00283 void ContextStyle::setSizeFactor( double factor )
00284 {
00285 m_sizeFactor = factor;
00286 }
00287
00288
00289 luPixel ContextStyle::getLineWidth( double factor ) const
00290 {
00291 return ptToLayoutUnitPixX( m_sizeFactor * lineWidth * factor );
00292 }
00293
00294 luPixel ContextStyle::getEmptyRectWidth( double factor ) const
00295 {
00296 return ptToLayoutUnitPixX( m_sizeFactor * m_baseSize * factor / 1.8 );
00297 }
00298
00299 luPixel ContextStyle::getEmptyRectHeight( double factor ) const
00300 {
00301 return ptToLayoutUnitPixX( m_sizeFactor * m_baseSize * factor / 1.8 );
00302 }
00303
00304
00305 ContextStyle::TextStyle ContextStyle::convertTextStyleFraction( TextStyle tstyle ) const
00306 {
00307 TextStyle result;
00308
00309 switch ( tstyle ){
00310 case displayStyle:
00311 result = textStyle;
00312 break;
00313 case textStyle:
00314 result = scriptStyle;
00315 break;
00316 default:
00317 result = scriptScriptStyle;
00318 break;
00319 }
00320
00321 return result;
00322 }
00323
00324
00325 ContextStyle::TextStyle ContextStyle::convertTextStyleIndex( TextStyle tstyle ) const
00326 {
00327 TextStyle result;
00328
00329 switch ( tstyle ){
00330 case displayStyle:
00331 result = scriptStyle;
00332 break;
00333 case textStyle:
00334 result = scriptStyle;
00335 break;
00336 default:
00337 result = scriptScriptStyle;
00338 break;
00339 }
00340
00341 return result;
00342 }
00343
00344
00345 void ContextStyle::setup()
00346 {
00347 luPt size = static_cast<luPt>( m_baseSize );
00348 QFont font = symbolFont;
00349 font.setPointSizeF( size );
00350 QFontMetrics fm( font );
00351
00352
00353 quad = ptToLayoutUnitPt( fm.width( 'M' ) );
00354
00355 font = QFont(defaultFont);
00356 font.setPointSizeF( size );
00357 QFontMetrics fm2( font );
00358
00359
00360
00361 m_axisHeight = ptToLayoutUnitPixY( pixelYToPt( fm2.strikeOutPos() ) );
00362 }
00363
00364
00365
00366 double ContextStyle::pixelToLayoutUnitX( double x ) const
00367 {
00368
00369
00370
00371 double m_layoutUnitFactor = 20.0;
00372
00373 return qRound( ( x * m_layoutUnitFactor * m_resolutionX ) / m_zoomedResolutionX );
00374 }
00375
00376 double ContextStyle::pixelToLayoutUnitY( double y ) const
00377 {
00378
00379
00380
00381 double m_layoutUnitFactor = 20.0;
00382 return qRound( ( y * m_layoutUnitFactor * m_resolutionY ) / m_zoomedResolutionY );
00383 }
00384
00385 double ContextStyle::layoutUnitToPixelX( double lupix ) const
00386 {
00387
00388
00389
00390 double m_layoutUnitFactor = 20.0;
00391 return ( lupix * m_zoomedResolutionX ) / ( m_layoutUnitFactor * m_resolutionX );
00392 }
00393
00394 double ContextStyle::layoutUnitToPixelY( double lupix ) const
00395 {
00396
00397
00398
00399 double m_layoutUnitFactor = 20.0;
00400 return ( lupix * m_zoomedResolutionY ) / ( m_layoutUnitFactor * m_resolutionY );
00401 }
00402
00403 double ContextStyle::layoutUnitToFontSize( double luSize, bool ) const
00404 {
00405
00406 return layoutUnitPtToPt( luSize ) * m_zoomedResolutionY;
00407
00408
00409
00410
00411 }
00412
00413 double StyleAttributes::sizeFactor() const
00414 {
00415 if ( m_size.empty() ) {
00416
00417 return 1.0;
00418 }
00419 return m_size.top();
00420 }
00421
00422 bool StyleAttributes::customMathVariant() const
00423 {
00424 if ( m_customMathVariant.empty() ) {
00425 return false;
00426 }
00427 return m_customMathVariant.top();
00428 }
00429
00430 CharStyle StyleAttributes::charStyle() const
00431 {
00432 if ( m_charStyle.empty() ) {
00433
00434 return anyChar;
00435 }
00436 return m_charStyle.top();
00437 }
00438
00439 CharFamily StyleAttributes::charFamily() const
00440 {
00441 if ( m_charFamily.empty() ) {
00442
00443 return anyFamily;
00444 }
00445 return m_charFamily.top();
00446 }
00447
00448 QColor StyleAttributes::color() const
00449 {
00450 if ( m_color.empty() ) {
00451
00452 return QColor( Qt::black );
00453
00454 }
00455 return m_color.top();
00456 }
00457
00458 QColor StyleAttributes::background() const
00459 {
00460 if ( m_background.empty() ) {
00461
00462 return QColor( Qt::color0 );
00463 }
00464 return m_background.top();
00465 }
00466
00467 QFont StyleAttributes::font() const
00468 {
00469 if ( m_font.empty() ) {
00470 return QFont();
00471 }
00472 return m_font.top();
00473 }
00474
00475 bool StyleAttributes::fontWeight() const
00476 {
00477 if ( m_fontWeight.empty() ) {
00478 return false;
00479 }
00480 return m_fontWeight.top();
00481 }
00482
00483 bool StyleAttributes::customFontWeight() const
00484 {
00485 if ( m_customFontWeight.empty() ) {
00486 return false;
00487 }
00488 return m_customFontWeight.top();
00489 }
00490
00491 bool StyleAttributes::fontStyle() const
00492 {
00493 if ( m_fontStyle.empty() ) {
00494 return false;
00495 }
00496 return m_fontStyle.top();
00497 }
00498
00499 bool StyleAttributes::customFontStyle() const
00500 {
00501 if ( m_customFontStyle.empty() ) {
00502 return false;
00503 }
00504 return m_customFontStyle.top();
00505 }
00506
00507 bool StyleAttributes::customFont() const
00508 {
00509 if ( m_customFontFamily.empty() ) {
00510 return false;
00511 }
00512 return m_customFontFamily.top();
00513 }
00514
00515 int StyleAttributes::scriptLevel() const
00516 {
00517 if ( m_scriptLevel.empty() ) {
00518 return 0;
00519 }
00520 return m_scriptLevel.top();
00521 }
00522
00523 double StyleAttributes::scriptSizeMultiplier() const
00524 {
00525 if ( m_scriptSizeMultiplier.empty() ) {
00526 return scriptsizemultiplier;
00527 }
00528 return m_scriptSizeMultiplier.top();
00529 }
00530
00531 double StyleAttributes::scriptMinSize() const
00532 {
00533 if ( m_scriptMinSize.empty() ) {
00534 return scriptminsize;
00535 }
00536 return m_scriptMinSize.top();
00537 }
00538
00539 double StyleAttributes::veryVeryThinMathSpace() const
00540 {
00541 if ( m_veryVeryThinMathSpace.empty() ) {
00542 return veryverythinmathspace;
00543 }
00544 return m_veryVeryThinMathSpace.top();
00545 }
00546
00547 double StyleAttributes::veryThinMathSpace() const
00548 {
00549 if ( m_veryThinMathSpace.empty() ) {
00550 return verythinmathspace;
00551 }
00552 return m_veryThinMathSpace.top();
00553 }
00554
00555 double StyleAttributes::thinMathSpace() const
00556 {
00557 if ( m_thinMathSpace.empty() ) {
00558 return thinmathspace;
00559 }
00560 return m_thinMathSpace.top();
00561 }
00562
00563 double StyleAttributes::mediumMathSpace() const
00564 {
00565 if ( m_mediumMathSpace.empty() ) {
00566 return mediummathspace;
00567 }
00568 return m_mediumMathSpace.top();
00569 }
00570
00571 double StyleAttributes::thickMathSpace() const
00572 {
00573 if ( m_thickMathSpace.empty() ) {
00574 return thickmathspace;
00575 }
00576 return m_thickMathSpace.top();
00577 }
00578
00579 double StyleAttributes::veryThickMathSpace() const
00580 {
00581 if ( m_veryThickMathSpace.empty() ) {
00582 return verythickmathspace;
00583 }
00584 return m_veryThickMathSpace.top();
00585 }
00586
00587 double StyleAttributes::veryVeryThickMathSpace() const
00588 {
00589 if ( m_veryVeryThickMathSpace.empty() ) {
00590 return veryverythickmathspace;
00591 }
00592 return m_veryVeryThickMathSpace.top();
00593 }
00594
00595 bool StyleAttributes::displayStyle() const
00596 {
00597 if ( m_displayStyle.empty() ) {
00598 return true;
00599 }
00600 return m_displayStyle.top();
00601 }
00602
00603 bool StyleAttributes::customDisplayStyle() const
00604 {
00605 if ( m_customDisplayStyle.empty() ) {
00606 return false;
00607 }
00608 return m_customDisplayStyle.top();
00609 }
00610
00611 double StyleAttributes::getSpace( SizeType type, double length ) const
00612 {
00613 switch ( type ) {
00614 case NegativeVeryVeryThinMathSpace:
00615 return - veryVeryThinMathSpace();
00616 case NegativeVeryThinMathSpace:
00617 return - veryThinMathSpace();
00618 case NegativeThinMathSpace:
00619 return - thinMathSpace();
00620 case NegativeMediumMathSpace:
00621 return - mediumMathSpace();
00622 case NegativeThickMathSpace:
00623 return - thickMathSpace();
00624 case NegativeVeryThickMathSpace:
00625 return - veryThickMathSpace();
00626 case NegativeVeryVeryThickMathSpace:
00627 return - veryVeryThickMathSpace();
00628 case VeryVeryThinMathSpace:
00629 return veryVeryThinMathSpace();
00630 case VeryThinMathSpace:
00631 return veryThinMathSpace();
00632 case ThinMathSpace:
00633 return thinMathSpace();
00634 case MediumMathSpace:
00635 return mediumMathSpace();
00636 case ThickMathSpace:
00637 return thickMathSpace();
00638 case VeryThickMathSpace:
00639 return veryThickMathSpace();
00640 case VeryVeryThickMathSpace:
00641 return veryVeryThickMathSpace();
00642 default:
00643 break;
00644 }
00645 return length;
00646 }
00647
00648 void StyleAttributes::resetSize()
00649 {
00650 if ( ! m_size.empty() ) {
00651 m_size.pop();
00652 }
00653 }
00654
00655 void StyleAttributes::resetCharStyle()
00656 {
00657 if ( ! m_charStyle.empty() ) {
00658 m_charStyle.pop();
00659 }
00660 }
00661
00662 void StyleAttributes::resetCharFamily()
00663 {
00664 if ( ! m_charFamily.empty() ) {
00665 m_charFamily.pop();
00666 }
00667 }
00668
00669 void StyleAttributes::resetColor()
00670 {
00671 if ( ! m_color.empty() ) {
00672 m_color.pop();
00673 }
00674 }
00675
00676 void StyleAttributes::resetBackground()
00677 {
00678 if ( ! m_background.empty() ) {
00679 m_background.pop();
00680 }
00681 }
00682
00683 void StyleAttributes::resetFontFamily()
00684 {
00685 if ( ! m_customFontFamily.empty() ) {
00686 if ( m_customFontFamily.pop() ) {
00687 if ( ! m_font.empty() ) {
00688 m_font.pop();
00689 }
00690 }
00691 }
00692 }
00693
00694 void StyleAttributes::resetFontWeight()
00695 {
00696 if ( ! m_customFontWeight.empty() ) {
00697 if ( m_customFontWeight.pop() ) {
00698 if ( ! m_fontWeight.empty() ) {
00699 m_fontWeight.pop();
00700 }
00701 }
00702 }
00703 }
00704
00705 void StyleAttributes::resetFontStyle()
00706 {
00707 if ( ! m_customFontStyle.empty() ) {
00708 if ( m_customFontStyle.pop() ) {
00709 if ( ! m_fontStyle.empty() ) {
00710 m_fontStyle.pop();
00711 }
00712 }
00713 }
00714 }
00715
00716 void StyleAttributes::resetScriptLevel()
00717 {
00718 if ( ! m_scriptLevel.empty() ) {
00719 m_scriptLevel.pop();
00720 }
00721 }
00722
00723 void StyleAttributes::resetScriptSizeMultiplier()
00724 {
00725 if ( ! m_scriptSizeMultiplier.empty() ) {
00726 m_scriptSizeMultiplier.pop();
00727 }
00728 }
00729
00730 void StyleAttributes::resetScriptMinSize()
00731 {
00732 if ( ! m_scriptMinSize.empty() ) {
00733 m_scriptMinSize.pop();
00734 }
00735 }
00736
00737 void StyleAttributes::resetVeryVeryThinMathSpace()
00738 {
00739 if ( ! m_veryVeryThinMathSpace.empty() ) {
00740 m_veryVeryThinMathSpace.pop();
00741 }
00742 }
00743
00744 void StyleAttributes::resetVeryThinMathSpace()
00745 {
00746 if ( ! m_veryThinMathSpace.empty() ) {
00747 m_veryThinMathSpace.pop();
00748 }
00749 }
00750
00751 void StyleAttributes::resetThinMathSpace()
00752 {
00753 if ( ! m_thinMathSpace.empty() ) {
00754 m_thinMathSpace.pop();
00755 }
00756 }
00757
00758 void StyleAttributes::resetMediumMathSpace()
00759 {
00760 if ( ! m_mediumMathSpace.empty() ) {
00761 m_mediumMathSpace.pop();
00762 }
00763 }
00764
00765 void StyleAttributes::resetThickMathSpace()
00766 {
00767 if ( ! m_thickMathSpace.empty() ) {
00768 m_thickMathSpace.pop();
00769 }
00770 }
00771
00772 void StyleAttributes::resetVeryThickMathSpace()
00773 {
00774 if ( ! m_veryThickMathSpace.empty() ) {
00775 m_veryThickMathSpace.pop();
00776 }
00777 }
00778
00779 void StyleAttributes::resetVeryVeryThickMathSpace()
00780 {
00781 if ( ! m_veryVeryThickMathSpace.empty() ) {
00782 m_veryVeryThickMathSpace.pop();
00783 }
00784 }
00785
00786 void StyleAttributes::resetDisplayStyle()
00787 {
00788 if ( ! m_customDisplayStyle.empty() ) {
00789 if ( m_customDisplayStyle.pop() ) {
00790 if ( ! m_displayStyle.empty() ) {
00791 m_displayStyle.pop();
00792 }
00793 }
00794 }
00795 }
00796
00797
00798 KFORMULA_NAMESPACE_END