lib Library API Documentation

elementtype.cc

00001 /* This file is part of the KDE project 00002 Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> 00003 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 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 * Converts CharStyle and CharFamily to the MathML 'mathvariant' 00041 * attribute (see MathML spec 3.2.2). 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 { 00106 return 0; 00107 } 00108 00109 luPt ElementType::getSpaceAfter( MultiElementType*, 00110 const ContextStyle&, 00111 ContextStyle::TextStyle ) 00112 { 00113 return 0; 00114 } 00115 00116 luPt ElementType::getSpaceAfter( OperatorType*, 00117 const ContextStyle&, 00118 ContextStyle::TextStyle ) 00119 { 00120 return 0; 00121 } 00122 00123 luPt ElementType::getSpaceAfter( RelationType*, 00124 const ContextStyle&, 00125 ContextStyle::TextStyle ) 00126 { 00127 return 0; 00128 } 00129 00130 luPt ElementType::getSpaceAfter( PunctuationType*, 00131 const ContextStyle&, 00132 ContextStyle::TextStyle ) 00133 { 00134 return 0; 00135 } 00136 00137 luPt ElementType::getSpaceAfter( BracketType*, 00138 const ContextStyle&, 00139 ContextStyle::TextStyle ) 00140 { 00141 return 0; 00142 } 00143 00144 luPt ElementType::getSpaceAfter( ComplexElementType*, 00145 const ContextStyle&, 00146 ContextStyle::TextStyle ) 00147 { 00148 return 0; 00149 } 00150 00151 luPt ElementType::getSpaceAfter( InnerElementType*, 00152 const ContextStyle&, 00153 ContextStyle::TextStyle ) 00154 { 00155 return 0; 00156 } 00157 00158 luPt ElementType::thinSpaceIfNotScript( const ContextStyle& context, 00159 ContextStyle::TextStyle tstyle ) 00160 { 00161 if ( !context.isScript( tstyle ) ) { 00162 return context.getThinSpace( tstyle ); 00163 } 00164 return 0; 00165 } 00166 00167 luPt ElementType::mediumSpaceIfNotScript( const ContextStyle& context, 00168 ContextStyle::TextStyle tstyle ) 00169 { 00170 if ( !context.isScript( tstyle ) ) { 00171 return context.getMediumSpace( tstyle ); 00172 } 00173 return 0; 00174 } 00175 00176 luPt ElementType::thickSpaceIfNotScript( const ContextStyle& context, 00177 ContextStyle::TextStyle tstyle ) 00178 { 00179 if ( !context.isScript( tstyle ) ) { 00180 return context.getThickSpace( tstyle ); 00181 } 00182 return 0; 00183 } 00184 00185 00186 QFont ElementType::getFont(const ContextStyle& context) 00187 { 00188 return context.getDefaultFont(); 00189 } 00190 00191 void ElementType::setUpPainter(const ContextStyle& context, QPainter& painter) 00192 { 00193 painter.setPen(context.getDefaultColor()); 00194 } 00195 00196 void ElementType::append( ElementType* element ) 00197 { 00198 element->prev = this; 00199 } 00200 00201 void ElementType::output() 00202 { 00203 kdDebug( DEBUGID ) << start() << " - " << end() << endl; 00204 } 00205 00206 void ElementType::saveMathML( SequenceElement* se, QDomDocument doc, QDomElement de ) 00207 { 00208 for ( uint i = from; i < to; ++i ) { 00209 se->getChild( i )->writeMathML( doc, de ); 00210 } 00211 } 00212 00213 00214 SequenceType::SequenceType( SequenceParser* parser ) 00215 : ElementType( parser ), last( 0 ) 00216 { 00217 while ( true ) { 00218 parser->nextToken(); 00219 //cerr << "SequenceType::SequenceType(): " << parser->getTokenType() << " " 00220 // << parser->getStart() << " " << parser->getEnd() << endl; 00221 if ( parser->getTokenType() == END ) { 00222 break; 00223 } 00224 ElementType* nextType = parser->getPrimitive(); 00225 if ( nextType == 0 ) { 00226 break; 00227 } 00228 if ( last != 0 ) { 00229 last->append( nextType ); 00230 } 00231 last = nextType; 00232 } 00233 } 00234 00235 SequenceType::~SequenceType() 00236 { 00237 delete last; 00238 } 00239 00240 00241 void SequenceType::output() 00242 { 00243 } 00244 00245 00246 MultiElementType::MultiElementType( SequenceParser* parser ) 00247 : ElementType( parser ) 00248 { 00249 for ( uint i = start(); i < end(); i++ ) { 00250 parser->setElementType( i, this ); 00251 } 00252 m_text = parser->text(); 00253 } 00254 00255 00256 luPt MultiElementType::getSpaceBefore( const ContextStyle& context, 00257 ContextStyle::TextStyle tstyle ) 00258 { 00259 if ( getPrev() != 0 ) { 00260 return getPrev()->getSpaceAfter( this, context, tstyle ); 00261 } 00262 return 0; 00263 } 00264 00265 luPt MultiElementType::getSpaceAfter( OperatorType*, 00266 const ContextStyle& context, 00267 ContextStyle::TextStyle tstyle ) 00268 { 00269 return mediumSpaceIfNotScript( context, tstyle ); 00270 } 00271 00272 luPt MultiElementType::getSpaceAfter( RelationType*, 00273 const ContextStyle& context, 00274 ContextStyle::TextStyle tstyle ) 00275 { 00276 return thickSpaceIfNotScript( context, tstyle ); 00277 } 00278 00279 luPt MultiElementType::getSpaceAfter( InnerElementType*, 00280 const ContextStyle& context, 00281 ContextStyle::TextStyle tstyle ) 00282 { 00283 return thinSpaceIfNotScript( context, tstyle ); 00284 } 00285 00286 00287 TextType::TextType( SequenceParser* parser ) 00288 : MultiElementType( parser ) 00289 { 00290 } 00291 00292 void TextType::saveMathML( SequenceElement* se, QDomDocument doc, QDomElement de ) 00293 { 00294 for ( uint i = start(); i < end(); ++i ) { 00295 QDomElement text = doc.createElement( "mi" ); 00296 BasicElement* be = se->getChild( i ); 00297 TextElement* te = static_cast<TextElement*>( be ); 00298 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily()); 00299 if ( !mathvariant.isNull() ) 00300 text.setAttribute( "mathvariant", mathvariant ); 00301 if ( be->getCharacter().latin1() != 0 ) { 00302 // A latin-1 character, we can save it as it is. 00303 text.appendChild( doc.createTextNode( be->getCharacter() ) ); 00304 } 00305 else { 00306 // An unicode char 00307 QString s; 00308 text.appendChild( doc.createEntityReference( s.sprintf( "#x%05X", be->getCharacter().unicode() ) ) ); 00309 } 00310 00311 if ( i != end() - 1 ) { 00312 QDomElement op = doc.createElement( "mo" ); 00313 op.appendChild( doc.createEntityReference( "InvisibleTimes" ) ); 00314 text.appendChild( op ); 00315 } 00316 de.appendChild( text ); 00317 } 00318 } 00319 00320 00321 NameType::NameType( SequenceParser* parser ) 00322 : MultiElementType( parser ) 00323 { 00324 } 00325 00326 void NameType::saveMathML( SequenceElement* se, QDomDocument doc, QDomElement de ) 00327 { 00328 se->getChild( start() )->writeMathML( doc, de ); 00329 00330 /* 00331 QDomElement name = doc.createElement( "mi" ); 00332 QString value; 00333 for ( uint i = start(); i < end(); ++i ) { 00334 BasicElement* be = se->getChild( i ); 00335 //TextElement* te = static_cast<TextElement*>( be ); 00336 value += be->getCharacter(); 00337 } 00338 name.appendChild( doc.createTextNode( value ) ); 00339 de.appendChild( name );*/ 00340 } 00341 00342 00343 QFont NameType::getFont(const ContextStyle& context) 00344 { 00345 return context.getNameFont(); 00346 } 00347 00348 NumberType::NumberType( SequenceParser* parser ) 00349 : MultiElementType( parser ) 00350 { 00351 } 00352 00353 QFont NumberType::getFont(const ContextStyle& context) 00354 { 00355 return context.getNumberFont(); 00356 } 00357 00358 void NumberType::setUpPainter(const ContextStyle& context, QPainter& painter) 00359 { 00360 painter.setPen(context.getNumberColor()); 00361 } 00362 00363 void NumberType::saveMathML( SequenceElement* se, QDomDocument doc, QDomElement de ) 00364 { 00365 QDomElement name = doc.createElement( "mn" ); 00366 QString value; 00367 for ( uint i = start(); i < end(); ++i ) { 00368 BasicElement* be = se->getChild( i ); 00369 value += be->getCharacter(); 00370 } 00371 TextElement* te = static_cast<TextElement*>( se->getChild( start() ) ); 00372 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); 00373 if ( !mathvariant.isNull() ) 00374 name.setAttribute( "mathvariant", mathvariant ); 00375 00376 name.appendChild( doc.createTextNode( value ) ); 00377 de.appendChild( name ); 00378 } 00379 00380 00381 SingleElementType::SingleElementType( SequenceParser* parser ) 00382 : ElementType( parser ) 00383 { 00384 parser->setElementType( start(), this ); 00385 } 00386 00387 AbstractOperatorType::AbstractOperatorType( SequenceParser* parser ) 00388 : SingleElementType( parser ) 00389 { 00390 } 00391 00392 void AbstractOperatorType::saveMathML( SequenceElement* se, QDomDocument doc, QDomElement de ) 00393 { 00394 QDomElement op = doc.createElement( "mo" ); 00395 BasicElement* be = se->getChild( start() ); 00396 if ( be->getCharacter().latin1() != 0 ) { 00397 // latin-1 char 00398 op.appendChild( doc.createTextNode( be->getCharacter() ) ); 00399 } 00400 else { 00401 // unicode char 00402 QString s; 00403 op.appendChild( doc.createEntityReference( s.sprintf( "#x%05X", be->getCharacter().unicode() ) ) ); 00404 } 00405 TextElement* te = static_cast<TextElement*>( be ); 00406 QString mathvariant = format2variant( te->getCharStyle(), te->getCharFamily() ); 00407 if ( !mathvariant.isNull() ) 00408 op.setAttribute( "mathvariant", mathvariant ); 00409 00410 de.appendChild( op ); 00411 } 00412 00413 OperatorType::OperatorType( SequenceParser* parser ) 00414 : AbstractOperatorType( parser ) 00415 { 00416 } 00417 00418 luPt OperatorType::getSpaceBefore( const ContextStyle& context, 00419 ContextStyle::TextStyle tstyle ) 00420 { 00421 if ( getPrev() != 0 ) { 00422 return getPrev()->getSpaceAfter( this, context, tstyle ); 00423 } 00424 return 0; 00425 } 00426 00427 luPt OperatorType::getSpaceAfter( MultiElementType*, 00428 const ContextStyle& context, 00429 ContextStyle::TextStyle tstyle ) 00430 { 00431 return mediumSpaceIfNotScript( context, tstyle ); 00432 } 00433 00434 luPt OperatorType::getSpaceAfter( BracketType*, 00435 const ContextStyle& context, 00436 ContextStyle::TextStyle tstyle ) 00437 { 00438 return mediumSpaceIfNotScript( context, tstyle ); 00439 } 00440 00441 luPt OperatorType::getSpaceAfter( ComplexElementType*, 00442 const ContextStyle& context, 00443 ContextStyle::TextStyle tstyle ) 00444 { 00445 return mediumSpaceIfNotScript( context, tstyle ); 00446 } 00447 00448 luPt OperatorType::getSpaceAfter( InnerElementType*, 00449 const ContextStyle& context, 00450 ContextStyle::TextStyle tstyle ) 00451 { 00452 return mediumSpaceIfNotScript( context, tstyle ); 00453 } 00454 00455 00456 QFont OperatorType::getFont(const ContextStyle& context) 00457 { 00458 return context.getOperatorFont(); 00459 } 00460 00461 void OperatorType::setUpPainter(const ContextStyle& context, QPainter& painter) 00462 { 00463 painter.setPen(context.getOperatorColor()); 00464 } 00465 00466 00467 RelationType::RelationType( SequenceParser* parser ) 00468 : AbstractOperatorType( parser ) 00469 { 00470 } 00471 00472 luPt RelationType::getSpaceBefore( const ContextStyle& context, 00473 ContextStyle::TextStyle tstyle ) 00474 { 00475 if ( getPrev() != 0 ) { 00476 return getPrev()->getSpaceAfter( this, context, tstyle ); 00477 } 00478 return 0; 00479 } 00480 00481 luPt RelationType::getSpaceAfter( MultiElementType*, 00482 const ContextStyle& context, 00483 ContextStyle::TextStyle tstyle ) 00484 { 00485 return thickSpaceIfNotScript( context, tstyle ); 00486 } 00487 00488 luPt RelationType::getSpaceAfter( BracketType*, 00489 const ContextStyle& context, 00490 ContextStyle::TextStyle tstyle ) 00491 { 00492 return thickSpaceIfNotScript( context, tstyle ); 00493 } 00494 00495 luPt RelationType::getSpaceAfter( ComplexElementType*, 00496 const ContextStyle& context, 00497 ContextStyle::TextStyle tstyle ) 00498 { 00499 return thickSpaceIfNotScript( context, tstyle ); 00500 } 00501 00502 luPt RelationType::getSpaceAfter( InnerElementType*, 00503 const ContextStyle& context, 00504 ContextStyle::TextStyle tstyle ) 00505 { 00506 return thickSpaceIfNotScript( context, tstyle ); 00507 } 00508 00509 QFont RelationType::getFont( const ContextStyle& context ) 00510 { 00511 return context.getOperatorFont(); 00512 } 00513 00514 void RelationType::setUpPainter( const ContextStyle& context, QPainter& painter ) 00515 { 00516 painter.setPen(context.getOperatorColor()); 00517 } 00518 00519 00520 00521 PunctuationType::PunctuationType( SequenceParser* parser ) 00522 : AbstractOperatorType( parser ) 00523 { 00524 } 00525 00526 luPt PunctuationType::getSpaceBefore( const ContextStyle& context, 00527 ContextStyle::TextStyle tstyle ) 00528 { 00529 if ( getPrev() != 0 ) { 00530 return getPrev()->getSpaceAfter( this, context, tstyle ); 00531 } 00532 return 0; 00533 } 00534 00535 luPt PunctuationType::getSpaceAfter( MultiElementType*, 00536 const ContextStyle& context, 00537 ContextStyle::TextStyle tstyle ) 00538 { 00539 return thinSpaceIfNotScript( context, tstyle ); 00540 } 00541 00542 luPt PunctuationType::getSpaceAfter( RelationType*, 00543 const ContextStyle& context, 00544 ContextStyle::TextStyle tstyle ) 00545 { 00546 return thickSpaceIfNotScript( context, tstyle ); 00547 } 00548 00549 luPt PunctuationType::getSpaceAfter( PunctuationType*, 00550 const ContextStyle& context, 00551 ContextStyle::TextStyle tstyle ) 00552 { 00553 return thinSpaceIfNotScript( context, tstyle ); 00554 } 00555 00556 luPt PunctuationType::getSpaceAfter( BracketType*, 00557 const ContextStyle& context, 00558 ContextStyle::TextStyle tstyle ) 00559 { 00560 return thinSpaceIfNotScript( context, tstyle ); 00561 } 00562 00563 luPt PunctuationType::getSpaceAfter( ComplexElementType*, 00564 const ContextStyle& context, 00565 ContextStyle::TextStyle tstyle ) 00566 { 00567 return thinSpaceIfNotScript( context, tstyle ); 00568 } 00569 00570 luPt PunctuationType::getSpaceAfter( InnerElementType*, 00571 const ContextStyle& context, 00572 ContextStyle::TextStyle tstyle ) 00573 { 00574 return thinSpaceIfNotScript( context, tstyle ); 00575 } 00576 00577 QFont PunctuationType::getFont( const ContextStyle& context ) 00578 { 00579 return context.getOperatorFont(); 00580 } 00581 00582 void PunctuationType::setUpPainter( const ContextStyle& context, QPainter& painter ) 00583 { 00584 painter.setPen( context.getDefaultColor() ); 00585 } 00586 00587 00588 BracketType::BracketType( SequenceParser* parser ) 00589 : SingleElementType( parser ) 00590 { 00591 } 00592 00593 luPt BracketType::getSpaceBefore( const ContextStyle& context, 00594 ContextStyle::TextStyle tstyle ) 00595 { 00596 if ( getPrev() != 0 ) { 00597 return getPrev()->getSpaceAfter( this, context, tstyle ); 00598 } 00599 return 0; 00600 } 00601 00602 luPt BracketType::getSpaceAfter( OperatorType*, 00603 const ContextStyle& context, 00604 ContextStyle::TextStyle tstyle ) 00605 { 00606 return mediumSpaceIfNotScript( context, tstyle ); 00607 } 00608 00609 luPt BracketType::getSpaceAfter( RelationType*, 00610 const ContextStyle& context, 00611 ContextStyle::TextStyle tstyle ) 00612 { 00613 return thickSpaceIfNotScript( context, tstyle ); 00614 } 00615 00616 luPt BracketType::getSpaceAfter( InnerElementType*, 00617 const ContextStyle& context, 00618 ContextStyle::TextStyle tstyle ) 00619 { 00620 return thinSpaceIfNotScript( context, tstyle ); 00621 } 00622 00623 00624 ComplexElementType::ComplexElementType( SequenceParser* parser ) 00625 : SingleElementType( parser ) 00626 { 00627 } 00628 00629 luPt ComplexElementType::getSpaceBefore( const ContextStyle& context, 00630 ContextStyle::TextStyle tstyle ) 00631 { 00632 if ( getPrev() != 0 ) { 00633 return getPrev()->getSpaceAfter( this, context, tstyle ); 00634 } 00635 return 0; 00636 } 00637 00638 luPt ComplexElementType::getSpaceAfter( OperatorType*, 00639 const ContextStyle& context, 00640 ContextStyle::TextStyle tstyle ) 00641 { 00642 return mediumSpaceIfNotScript( context, tstyle ); 00643 } 00644 00645 luPt ComplexElementType::getSpaceAfter( RelationType*, 00646 const ContextStyle& context, 00647 ContextStyle::TextStyle tstyle ) 00648 { 00649 return thickSpaceIfNotScript( context, tstyle ); 00650 } 00651 00652 luPt ComplexElementType::getSpaceAfter( InnerElementType*, 00653 const ContextStyle& context, 00654 ContextStyle::TextStyle tstyle ) 00655 { 00656 return thinSpaceIfNotScript( context, tstyle ); 00657 } 00658 00659 00660 InnerElementType::InnerElementType( SequenceParser* parser ) 00661 : SingleElementType( parser ) 00662 { 00663 } 00664 00665 luPt InnerElementType::getSpaceBefore( const ContextStyle& context, 00666 ContextStyle::TextStyle tstyle ) 00667 { 00668 if ( getPrev() != 0 ) { 00669 return getPrev()->getSpaceAfter( this, context, tstyle ); 00670 } 00671 return 0; 00672 } 00673 00674 luPt InnerElementType::getSpaceAfter( MultiElementType*, 00675 const ContextStyle& context, 00676 ContextStyle::TextStyle tstyle ) 00677 { 00678 return thinSpaceIfNotScript( context, tstyle ); 00679 } 00680 00681 luPt InnerElementType::getSpaceAfter( OperatorType*, 00682 const ContextStyle& context, 00683 ContextStyle::TextStyle tstyle ) 00684 { 00685 return mediumSpaceIfNotScript( context, tstyle ); 00686 } 00687 00688 luPt InnerElementType::getSpaceAfter( RelationType*, 00689 const ContextStyle& context, 00690 ContextStyle::TextStyle tstyle ) 00691 { 00692 return thickSpaceIfNotScript( context, tstyle ); 00693 } 00694 00695 luPt InnerElementType::getSpaceAfter( PunctuationType*, 00696 const ContextStyle& context, 00697 ContextStyle::TextStyle tstyle ) 00698 { 00699 return thinSpaceIfNotScript( context, tstyle ); 00700 } 00701 00702 luPt InnerElementType::getSpaceAfter( BracketType*, 00703 const ContextStyle& context, 00704 ContextStyle::TextStyle tstyle ) 00705 { 00706 return thinSpaceIfNotScript( context, tstyle ); 00707 } 00708 00709 luPt InnerElementType::getSpaceAfter( ComplexElementType*, 00710 const ContextStyle& context, 00711 ContextStyle::TextStyle tstyle ) 00712 { 00713 return thinSpaceIfNotScript( context, tstyle ); 00714 } 00715 00716 luPt InnerElementType::getSpaceAfter( InnerElementType*, 00717 const ContextStyle& context, 00718 ContextStyle::TextStyle tstyle ) 00719 { 00720 return thinSpaceIfNotScript( context, tstyle ); 00721 } 00722 00723 00724 KFORMULA_NAMESPACE_END
KDE Logo
This file is part of the documentation for lib Library Version 1.3.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Sep 24 18:22:22 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003