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         de.appendChild( text );
00312         if ( i != end() - 1 ) {
00313             QDomElement op = doc.createElement( "mo" );
00314             op.appendChild( doc.createEntityReference( "InvisibleTimes" ) );
00315             de.appendChild( op );
00316         }
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.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 13:19:21 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2003