00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qfont.h>
00022 #include <qfontmetrics.h>
00023 #include <qpainter.h>
00024
00025 #include <kdebug.h>
00026
00027 #include "basicelement.h"
00028 #include "contextstyle.h"
00029 #include "elementtype.h"
00030 #include "sequenceelement.h"
00031 #include "sequenceparser.h"
00032 #include "textelement.h"
00033
00034
00035 KFORMULA_NAMESPACE_BEGIN
00036
00037 int ElementType::evilDestructionCount = 0;
00038
00039
00040
00041
00042
00043 QString format2variant( CharStyle style, CharFamily family )
00044 {
00045 QString result;
00046
00047 switch( family ) {
00048 case normalFamily:
00049 case anyFamily:
00050 switch( style ) {
00051 case normalChar:
00052 result = "normal"; break;
00053 case boldChar:
00054 result = "bold"; break;
00055 case italicChar:
00056 result = "italic"; break;
00057 case boldItalicChar:
00058 result = "bold-italic"; break;
00059 case anyChar:
00060 break;
00061 }
00062 break;
00063 case scriptFamily:
00064 result = "script";
00065 if ( style == boldChar || style == boldItalicChar )
00066 result = "bold-" + result;
00067 break;
00068 case frakturFamily:
00069 result = "fraktur";
00070 if ( style == boldChar || style == boldItalicChar )
00071 result = "bold-" + result;
00072 break;
00073 case doubleStruckFamily:
00074 result = "double-struck"; break;
00075 }
00076
00077 return result;
00078 }
00079
00080 ElementType::ElementType( SequenceParser* parser )
00081 : from( parser->getStart() ), to( parser->getEnd() ), prev( 0 )
00082 {
00083 evilDestructionCount++;
00084 }
00085
00086 ElementType::~ElementType()
00087 {
00088 delete prev;
00089 evilDestructionCount--;
00090 }
00091
00092
00093 QString ElementType::text( SequenceElement* seq ) const
00094 {
00095 QString str;
00096 for ( uint i=start(); i<end(); ++i ) {
00097 str.append( seq->getChild( i )->getCharacter() );
00098 }
00099 return str;
00100 }
00101
00102
00103 luPt ElementType::getSpaceBefore( const ContextStyle&,
00104 ContextStyle::TextStyle,
00105 double )
00106 {
00107 return 0;
00108 }
00109
00110 luPt ElementType::getSpaceAfter( MultiElementType*,
00111 const ContextStyle&,
00112 ContextStyle::TextStyle,
00113 double )
00114 {
00115 return 0;
00116 }
00117
00118 luPt ElementType::getSpaceAfter( OperatorType*,
00119 const ContextStyle&,
00120 ContextStyle::TextStyle,
00121 double )
00122 {
00123 return 0;
00124 }
00125
00126 luPt ElementType::getSpaceAfter( RelationType*,
00127 const ContextStyle&,
00128 ContextStyle::TextStyle,
00129 double )
00130 {
00131 return 0;
00132 }
00133
00134 luPt ElementType::getSpaceAfter( PunctuationType*,
00135 const ContextStyle&,
00136 ContextStyle::TextStyle,
00137 double )
00138 {
00139 return 0;
00140 }
00141
00142 luPt ElementType::getSpaceAfter( BracketType*,
00143 const ContextStyle&,
00144 ContextStyle::TextStyle,
00145 double )
00146 {
00147 return 0;
00148 }
00149
00150 luPt ElementType::getSpaceAfter( ComplexElementType*,
00151 const ContextStyle&,
00152 ContextStyle::TextStyle,
00153 double )
00154 {
00155 return 0;
00156 }
00157
00158 luPt ElementType::getSpaceAfter( InnerElementType*,
00159 const ContextStyle&,
00160 ContextStyle::TextStyle,
00161 double )
00162 {
00163 return 0;
00164 }
00165
00166 luPt ElementType::thinSpaceIfNotScript( const ContextStyle& context,
00167 ContextStyle::TextStyle tstyle,
00168 double factor )
00169 {
00170 if ( !context.isScript( tstyle ) ) {
00171 return context.getThinSpace( tstyle, factor );
00172 }
00173 return 0;
00174 }
00175
00176 luPt ElementType::mediumSpaceIfNotScript( const ContextStyle& context,
00177 ContextStyle::TextStyle tstyle,
00178 double factor )
00179 {
00180 if ( !context.isScript( tstyle ) ) {
00181 return context.getMediumSpace( tstyle, factor );
00182 }
00183 return 0;
00184 }
00185
00186 luPt ElementType::thickSpaceIfNotScript( const ContextStyle& context,
00187 ContextStyle::TextStyle tstyle,
00188 double factor )
00189 {
00190 if ( !context.isScript( tstyle ) ) {
00191 return context.getThickSpace( tstyle, factor );
00192 }
00193 return 0;
00194 }
00195
00196
00197 QFont ElementType::getFont(const ContextStyle& context)
00198 {
00199 return context.getDefaultFont();
00200 }
00201
00202 void ElementType::setUpPainter(const ContextStyle& context, QPainter& painter)
00203 {
00204 painter.setPen(context.getDefaultColor());
00205 }
00206
00207 void ElementType::append( ElementType* element )
00208 {
00209 element->prev = this;
00210 }
00211
00212 void ElementType::output()
00213 {
00214 kdDebug( DEBUGID ) << start() << " - " << end() << endl;
00215 }
00216
00217 void ElementType::saveMathML( SequenceElement* se, QDomDocument& doc, QDomElement de, bool oasisFormat )
00218 {
00219 for ( uint i = from; i < to; ++i ) {
00220 se->getChild( i )->writeMathML( doc, de, oasisFormat );
00221 }
00222 }
00223
00224
00225 SequenceType::SequenceType( SequenceParser* parser )
00226 : ElementType( parser ), last( 0 )
00227 {
00228 while ( true ) {
00229 parser->nextToken();
00230
00231
00232 if ( parser->getTokenType() == END ) {
00233 break;
00234 }
00235 ElementType* nextType = parser->getPrimitive();
00236 if ( nextType == 0 ) {
00237 break;
00238 }
00239 if ( last != 0 ) {
00240 last->append( nextType );
00241 }
00242 last = nextType;
00243 }
00244 }
00245
00246 SequenceType::~SequenceType()
00247 {
00248 delete last;
00249 }
00250
00251
00252 void SequenceType::output()
00253 {
00254 }
00255
00256
00257 MultiElementType::MultiElementType( SequenceParser* parser )
00258 : ElementType( parser )
00259 {
00260 for ( uint i = start(); i < end(); i++ ) {
00261 parser->setElementType( i, this );
00262 }
00263 m_text = parser->text();
00264 }
00265
00266
00267 luPt MultiElementType::getSpaceBefore( const ContextStyle& context,
00268 ContextStyle::TextStyle tstyle,
00269 double factor )
00270 {
00271 if ( getPrev() != 0 ) {
00272 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00273 }
00274 return 0;
00275 }
00276
00277 luPt MultiElementType::getSpaceAfter( OperatorType*,
00278 const ContextStyle& context,
00279 ContextStyle::TextStyle tstyle,
00280 double factor )
00281 {
00282 return mediumSpaceIfNotScript( context, tstyle, factor );
00283 }
00284
00285 luPt MultiElementType::getSpaceAfter( RelationType*,
00286 const ContextStyle& context,
00287 ContextStyle::TextStyle tstyle,
00288 double factor )
00289 {
00290 return thickSpaceIfNotScript( context, tstyle, factor );
00291 }
00292
00293 luPt MultiElementType::getSpaceAfter( InnerElementType*,
00294 const ContextStyle& context,
00295 ContextStyle::TextStyle tstyle,
00296 double factor )
00297 {
00298 return thinSpaceIfNotScript( context, tstyle, factor );
00299 }
00300
00301
00302 TextType::TextType( SequenceParser* parser )
00303 : MultiElementType( parser )
00304 {
00305 }
00306
00307 void TextType::saveMathML( SequenceElement* se, QDomDocument& doc, QDomElement de, bool oasisFormat )
00308 {
00309 for ( uint i = start(); i < end(); ++i ) {
00310 QDomElement text = doc.createElement( oasisFormat ? "math:mi" : "mi" );
00311 BasicElement* be = se->getChild( i );
00312 TextElement* te = static_cast<TextElement*>( be );
00313 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily());
00314 if ( !mathvariant.isNull() )
00315 text.setAttribute( "mathvariant", mathvariant );
00316
00317 text.appendChild( doc.createTextNode( be->getCharacter() ) );
00318
00319 de.appendChild( text );
00320 if ( i != end() - 1 ) {
00321 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00322 op.appendChild( doc.createEntityReference( "InvisibleTimes" ) );
00323 de.appendChild( op );
00324 }
00325 }
00326 }
00327
00328
00329 NameType::NameType( SequenceParser* parser )
00330 : MultiElementType( parser )
00331 {
00332 }
00333
00334 void NameType::saveMathML( SequenceElement* se, QDomDocument& doc, QDomElement de, bool oasisFormat )
00335 {
00336 se->getChild( start() )->writeMathML( doc, de, oasisFormat );
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 }
00349
00350
00351 QFont NameType::getFont(const ContextStyle& context)
00352 {
00353 return context.getNameFont();
00354 }
00355
00356 NumberType::NumberType( SequenceParser* parser )
00357 : MultiElementType( parser )
00358 {
00359 }
00360
00361 QFont NumberType::getFont(const ContextStyle& context)
00362 {
00363 return context.getNumberFont();
00364 }
00365
00366 void NumberType::setUpPainter(const ContextStyle& context, QPainter& painter)
00367 {
00368 painter.setPen(context.getNumberColor());
00369 }
00370
00371 void NumberType::saveMathML( SequenceElement* se, QDomDocument& doc, QDomElement de, bool oasisFormat )
00372 {
00373 QDomElement name = doc.createElement( oasisFormat ? "math:mn" : "mn" );
00374 QString value;
00375 for ( uint i = start(); i < end(); ++i ) {
00376 BasicElement* be = se->getChild( i );
00377 value += be->getCharacter();
00378 }
00379 TextElement* te = static_cast<TextElement*>( se->getChild( start() ) );
00380 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() );
00381 if ( !mathvariant.isNull() )
00382 name.setAttribute( "mathvariant", mathvariant );
00383
00384 name.appendChild( doc.createTextNode( value ) );
00385 de.appendChild( name );
00386 }
00387
00388
00389 SingleElementType::SingleElementType( SequenceParser* parser )
00390 : ElementType( parser )
00391 {
00392 parser->setElementType( start(), this );
00393 }
00394
00395 AbstractOperatorType::AbstractOperatorType( SequenceParser* parser )
00396 : SingleElementType( parser )
00397 {
00398 }
00399
00400 void AbstractOperatorType::saveMathML( SequenceElement* se, QDomDocument& doc, QDomElement de, bool oasisFormat )
00401 {
00402 QDomElement op = doc.createElement( oasisFormat ? "math:mo" : "mo" );
00403 BasicElement* be = se->getChild( start() );
00404 if ( be->getCharacter().latin1() != 0 ) {
00405
00406 op.appendChild( doc.createTextNode( be->getCharacter() ) );
00407 }
00408 else {
00409
00410 QString s;
00411 op.appendChild( doc.createEntityReference( s.sprintf( "#x%05X", be->getCharacter().unicode() ) ) );
00412 }
00413 TextElement* te = static_cast<TextElement*>( be );
00414 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() );
00415 if ( !mathvariant.isNull() )
00416 op.setAttribute( "mathvariant", mathvariant );
00417
00418 de.appendChild( op );
00419 }
00420
00421 OperatorType::OperatorType( SequenceParser* parser )
00422 : AbstractOperatorType( parser )
00423 {
00424 }
00425
00426 luPt OperatorType::getSpaceBefore( const ContextStyle& context,
00427 ContextStyle::TextStyle tstyle,
00428 double factor )
00429 {
00430 if ( getPrev() != 0 ) {
00431 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00432 }
00433 return 0;
00434 }
00435
00436 luPt OperatorType::getSpaceAfter( MultiElementType*,
00437 const ContextStyle& context,
00438 ContextStyle::TextStyle tstyle,
00439 double factor )
00440 {
00441 return mediumSpaceIfNotScript( context, tstyle, factor );
00442 }
00443
00444 luPt OperatorType::getSpaceAfter( BracketType*,
00445 const ContextStyle& context,
00446 ContextStyle::TextStyle tstyle,
00447 double factor )
00448 {
00449 return mediumSpaceIfNotScript( context, tstyle, factor );
00450 }
00451
00452 luPt OperatorType::getSpaceAfter( ComplexElementType*,
00453 const ContextStyle& context,
00454 ContextStyle::TextStyle tstyle,
00455 double factor )
00456 {
00457 return mediumSpaceIfNotScript( context, tstyle, factor );
00458 }
00459
00460 luPt OperatorType::getSpaceAfter( InnerElementType*,
00461 const ContextStyle& context,
00462 ContextStyle::TextStyle tstyle,
00463 double factor )
00464 {
00465 return mediumSpaceIfNotScript( context, tstyle, factor );
00466 }
00467
00468
00469 QFont OperatorType::getFont(const ContextStyle& context)
00470 {
00471 return context.getOperatorFont();
00472 }
00473
00474 void OperatorType::setUpPainter(const ContextStyle& context, QPainter& painter)
00475 {
00476 painter.setPen(context.getOperatorColor());
00477 }
00478
00479
00480 RelationType::RelationType( SequenceParser* parser )
00481 : AbstractOperatorType( parser )
00482 {
00483 }
00484
00485 luPt RelationType::getSpaceBefore( const ContextStyle& context,
00486 ContextStyle::TextStyle tstyle,
00487 double factor )
00488 {
00489 if ( getPrev() != 0 ) {
00490 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00491 }
00492 return 0;
00493 }
00494
00495 luPt RelationType::getSpaceAfter( MultiElementType*,
00496 const ContextStyle& context,
00497 ContextStyle::TextStyle tstyle,
00498 double factor )
00499 {
00500 return thickSpaceIfNotScript( context, tstyle, factor );
00501 }
00502
00503 luPt RelationType::getSpaceAfter( BracketType*,
00504 const ContextStyle& context,
00505 ContextStyle::TextStyle tstyle,
00506 double factor )
00507 {
00508 return thickSpaceIfNotScript( context, tstyle, factor );
00509 }
00510
00511 luPt RelationType::getSpaceAfter( ComplexElementType*,
00512 const ContextStyle& context,
00513 ContextStyle::TextStyle tstyle,
00514 double factor )
00515 {
00516 return thickSpaceIfNotScript( context, tstyle, factor );
00517 }
00518
00519 luPt RelationType::getSpaceAfter( InnerElementType*,
00520 const ContextStyle& context,
00521 ContextStyle::TextStyle tstyle,
00522 double factor )
00523 {
00524 return thickSpaceIfNotScript( context, tstyle, factor );
00525 }
00526
00527 QFont RelationType::getFont( const ContextStyle& context )
00528 {
00529 return context.getOperatorFont();
00530 }
00531
00532 void RelationType::setUpPainter( const ContextStyle& context, QPainter& painter )
00533 {
00534 painter.setPen(context.getOperatorColor());
00535 }
00536
00537
00538
00539 PunctuationType::PunctuationType( SequenceParser* parser )
00540 : AbstractOperatorType( parser )
00541 {
00542 }
00543
00544 luPt PunctuationType::getSpaceBefore( const ContextStyle& context,
00545 ContextStyle::TextStyle tstyle,
00546 double factor )
00547 {
00548 if ( getPrev() != 0 ) {
00549 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00550 }
00551 return 0;
00552 }
00553
00554 luPt PunctuationType::getSpaceAfter( MultiElementType*,
00555 const ContextStyle& context,
00556 ContextStyle::TextStyle tstyle,
00557 double factor )
00558 {
00559 return thinSpaceIfNotScript( context, tstyle, factor );
00560 }
00561
00562 luPt PunctuationType::getSpaceAfter( RelationType*,
00563 const ContextStyle& context,
00564 ContextStyle::TextStyle tstyle,
00565 double factor )
00566 {
00567 return thickSpaceIfNotScript( context, tstyle, factor );
00568 }
00569
00570 luPt PunctuationType::getSpaceAfter( PunctuationType*,
00571 const ContextStyle& context,
00572 ContextStyle::TextStyle tstyle,
00573 double factor )
00574 {
00575 return thinSpaceIfNotScript( context, tstyle, factor );
00576 }
00577
00578 luPt PunctuationType::getSpaceAfter( BracketType*,
00579 const ContextStyle& context,
00580 ContextStyle::TextStyle tstyle,
00581 double factor )
00582 {
00583 return thinSpaceIfNotScript( context, tstyle, factor );
00584 }
00585
00586 luPt PunctuationType::getSpaceAfter( ComplexElementType*,
00587 const ContextStyle& context,
00588 ContextStyle::TextStyle tstyle,
00589 double factor )
00590 {
00591 return thinSpaceIfNotScript( context, tstyle, factor );
00592 }
00593
00594 luPt PunctuationType::getSpaceAfter( InnerElementType*,
00595 const ContextStyle& context,
00596 ContextStyle::TextStyle tstyle,
00597 double factor )
00598 {
00599 return thinSpaceIfNotScript( context, tstyle, factor );
00600 }
00601
00602 QFont PunctuationType::getFont( const ContextStyle& context )
00603 {
00604 return context.getOperatorFont();
00605 }
00606
00607 void PunctuationType::setUpPainter( const ContextStyle& context, QPainter& painter )
00608 {
00609 painter.setPen( context.getDefaultColor() );
00610 }
00611
00612
00613 BracketType::BracketType( SequenceParser* parser )
00614 : SingleElementType( parser )
00615 {
00616 }
00617
00618 luPt BracketType::getSpaceBefore( const ContextStyle& context,
00619 ContextStyle::TextStyle tstyle,
00620 double factor )
00621 {
00622 if ( getPrev() != 0 ) {
00623 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00624 }
00625 return 0;
00626 }
00627
00628 luPt BracketType::getSpaceAfter( OperatorType*,
00629 const ContextStyle& context,
00630 ContextStyle::TextStyle tstyle,
00631 double factor )
00632 {
00633 return mediumSpaceIfNotScript( context, tstyle, factor );
00634 }
00635
00636 luPt BracketType::getSpaceAfter( RelationType*,
00637 const ContextStyle& context,
00638 ContextStyle::TextStyle tstyle,
00639 double factor )
00640 {
00641 return thickSpaceIfNotScript( context, tstyle, factor );
00642 }
00643
00644 luPt BracketType::getSpaceAfter( InnerElementType*,
00645 const ContextStyle& context,
00646 ContextStyle::TextStyle tstyle,
00647 double factor )
00648 {
00649 return thinSpaceIfNotScript( context, tstyle, factor );
00650 }
00651
00652
00653 ComplexElementType::ComplexElementType( SequenceParser* parser )
00654 : SingleElementType( parser )
00655 {
00656 }
00657
00658 luPt ComplexElementType::getSpaceBefore( const ContextStyle& context,
00659 ContextStyle::TextStyle tstyle,
00660 double factor )
00661 {
00662 if ( getPrev() != 0 ) {
00663 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00664 }
00665 return 0;
00666 }
00667
00668 luPt ComplexElementType::getSpaceAfter( OperatorType*,
00669 const ContextStyle& context,
00670 ContextStyle::TextStyle tstyle,
00671 double factor )
00672 {
00673 return mediumSpaceIfNotScript( context, tstyle, factor );
00674 }
00675
00676 luPt ComplexElementType::getSpaceAfter( RelationType*,
00677 const ContextStyle& context,
00678 ContextStyle::TextStyle tstyle,
00679 double factor )
00680 {
00681 return thickSpaceIfNotScript( context, tstyle, factor );
00682 }
00683
00684 luPt ComplexElementType::getSpaceAfter( InnerElementType*,
00685 const ContextStyle& context,
00686 ContextStyle::TextStyle tstyle,
00687 double factor )
00688 {
00689 return thinSpaceIfNotScript( context, tstyle, factor );
00690 }
00691
00692
00693 InnerElementType::InnerElementType( SequenceParser* parser )
00694 : SingleElementType( parser )
00695 {
00696 }
00697
00698 luPt InnerElementType::getSpaceBefore( const ContextStyle& context,
00699 ContextStyle::TextStyle tstyle,
00700 double factor )
00701 {
00702 if ( getPrev() != 0 ) {
00703 return getPrev()->getSpaceAfter( this, context, tstyle, factor );
00704 }
00705 return 0;
00706 }
00707
00708 luPt InnerElementType::getSpaceAfter( MultiElementType*,
00709 const ContextStyle& context,
00710 ContextStyle::TextStyle tstyle,
00711 double factor )
00712 {
00713 return thinSpaceIfNotScript( context, tstyle, factor );
00714 }
00715
00716 luPt InnerElementType::getSpaceAfter( OperatorType*,
00717 const ContextStyle& context,
00718 ContextStyle::TextStyle tstyle,
00719 double factor )
00720 {
00721 return mediumSpaceIfNotScript( context, tstyle, factor );
00722 }
00723
00724 luPt InnerElementType::getSpaceAfter( RelationType*,
00725 const ContextStyle& context,
00726 ContextStyle::TextStyle tstyle,
00727 double factor )
00728 {
00729 return thickSpaceIfNotScript( context, tstyle, factor );
00730 }
00731
00732 luPt InnerElementType::getSpaceAfter( PunctuationType*,
00733 const ContextStyle& context,
00734 ContextStyle::TextStyle tstyle,
00735 double factor )
00736 {
00737 return thinSpaceIfNotScript( context, tstyle, factor );
00738 }
00739
00740 luPt InnerElementType::getSpaceAfter( BracketType*,
00741 const ContextStyle& context,
00742 ContextStyle::TextStyle tstyle,
00743 double factor )
00744 {
00745 return thinSpaceIfNotScript( context, tstyle, factor );
00746 }
00747
00748 luPt InnerElementType::getSpaceAfter( ComplexElementType*,
00749 const ContextStyle& context,
00750 ContextStyle::TextStyle tstyle,
00751 double factor )
00752 {
00753 return thinSpaceIfNotScript( context, tstyle, factor );
00754 }
00755
00756 luPt InnerElementType::getSpaceAfter( InnerElementType*,
00757 const ContextStyle& context,
00758 ContextStyle::TextStyle tstyle,
00759 double factor )
00760 {
00761 return thinSpaceIfNotScript( context, tstyle, factor );
00762 }
00763
00764
00765 KFORMULA_NAMESPACE_END