F:/KPlato/koffice/libs/kformula/TextElement.cpp

Aller à la documentation de ce fichier.
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                  2006 Martin Pfeiffer <hubipete@gmx.net>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "TextElement.h"
00023 
00024 
00025 #include <QFontMetrics>
00026 #include <QPainter>
00027 
00028 #include <kdebug.h>
00029 
00030 #include "BasicElement.h"
00031 #include "contextstyle.h"
00032 #include "fontstyle.h"
00033 #include "FormulaElement.h"
00034 #include "kformulacommand.h"
00035 #include "SequenceElement.h"
00036 #include "symboltable.h"
00037 
00038 
00039 namespace KFormula {
00040 
00041 TextElement::TextElement( BasicElement* parent ) : BasicElement(parent),
00042                                                    character(' '),
00043                                                    symbol(false)
00044 {
00045     charStyle( anyChar );
00046     charFamily( anyFamily );
00047 }
00048 
00049 const QList<BasicElement*> TextElement::childElements()
00050 {
00051     return QList<BasicElement*>();
00052 }
00053 
00054 void TextElement::readMathML( const QDomElement& element )
00055 {
00056 }
00057 
00058 void TextElement::writeMathML( KoXmlWriter* writer, bool oasisFormat )
00059 {
00060 }
00061 
00062 
00063 TokenType TextElement::getTokenType() const
00064 {
00065     if ( isSymbol() ) {
00066         return getSymbolTable().charClass( character );
00067     }
00068 
00069     switch ( character.unicode() ) {
00070     case '+':
00071     case '-':
00072     case '*':
00073         //case '/':  because it counts as text -- no extra spaces
00074         return BINOP;
00075     case '=':
00076     case '<':
00077     case '>':
00078         return RELATION;
00079     case ',':
00080     case ';':
00081     case ':':
00082         return PUNCTUATION;
00083     case '\\':
00084         return SEPARATOR;
00085     case '\0':
00086         return ELEMENT;
00087     default:
00088         if ( character.isNumber() ) {
00089             return NUMBER;
00090         }
00091         else {
00092             return ORDINARY;
00093         }
00094     }
00095 }
00096 
00097 
00098 
00099 bool TextElement::isInvisible() const
00100 {
00101     /*if (getElementType() != 0) {
00102         return getElementType()->isInvisible(*this);
00103     }*/
00104     // no longer needed as BasicElement implements this
00105     return false;
00106 }
00107 
00108 
00113 void TextElement::calcSizes(const ContextStyle& context, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle /*istyle*/)
00114 {
00115     luPt mySize = context.getAdjustedSize( tstyle );
00116     //kDebug( DEBUGID ) << "TextElement::calcSizes size=" << mySize << endl;
00117 
00118     QFont font = getFont( context );
00119     font.setPointSizeF( context.layoutUnitPtToPt( mySize ) );
00120 
00121     QFontMetrics fm( font );
00122     QChar ch = getRealCharacter(context);
00123     if ( ch != QChar::Null ) {
00124         QRect bound = fm.boundingRect( ch );
00125         setWidth( context.ptToLayoutUnitPt( fm.width( ch ) ) );
00126         setHeight( context.ptToLayoutUnitPt( bound.height() ) );
00127         setBaseline( context.ptToLayoutUnitPt( -bound.top() ) );
00128 
00129         // There are some glyphs in TeX that have
00130         // baseline==0. (\int, \sum, \prod)
00131         if ( getBaseline() == 0 ) {
00132             //setBaseline( getHeight()/2 + context.axisHeight( tstyle ) );
00133             setBaseline( -1 );
00134         }
00135     }
00136     else {
00137         setWidth( qRound( context.getEmptyRectWidth() * 2./3. ) );
00138         setHeight( qRound( context.getEmptyRectHeight() * 2./3. ) );
00139         setBaseline( getHeight() );
00140     }
00141 
00142     //kDebug( DEBUGID ) << "height: " << getHeight() << endl;
00143     //kDebug( DEBUGID ) << "width: " << getWidth() << endl;
00144 }
00145 
00151 void TextElement::draw( QPainter& painter, const LuPixelRect& /*r*/,
00152                         const ContextStyle& context,
00153                         ContextStyle::TextStyle tstyle,
00154                         ContextStyle::IndexStyle /*istyle*/,
00155                         const LuPixelPoint& parentOrigin )
00156 {
00157     LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() );
00158     //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) )
00159     //    return;
00160 
00161     setUpPainter( context, painter );
00162 
00163     luPt mySize = context.getAdjustedSize( tstyle );
00164     QFont font = getFont( context );
00165     font.setPointSizeF( context.layoutUnitToFontSize( mySize, false ) );
00166     painter.setFont( font );
00167 
00168     // Each starting element draws the whole token
00169 /*    ElementType* token = getElementType();
00170     if ( ( token != 0 ) && !symbol ) {
00171         QString text = token->text( static_cast<SequenceElement*>( getParent() ) );
00172         painter.drawText( context.layoutUnitToPixelX( myPos.x() ),
00173                           context.layoutUnitToPixelY( myPos.y()+getBaseline() ),
00174                           text );
00175     }
00176     else {
00177         //kDebug() << "draw char" << endl;
00178         QChar ch = getRealCharacter(context);
00179         if ( ch != QChar::Null ) {
00180             luPixel bl = getBaseline();
00181             if ( bl == -1 ) {
00182                 // That's quite hacky and actually not the way it's
00183                 // meant to be. You shouldn't calculate a lot in
00184                 // draw. But I don't see how else to deal with
00185                 // baseline==0 glyphs without yet another flag.
00186                 bl = -( getHeight()/2 + context.axisHeight( tstyle ) );
00187             }
00188             painter.drawText( context.layoutUnitToPixelX( myPos.x() ),
00189                               context.layoutUnitToPixelY( myPos.y()+bl ),
00190                               ch );
00191         }
00192         else {
00193             painter.setPen( QPen( context.getErrorColor(),
00194                                   context.layoutUnitToPixelX( context.getLineWidth() ) ) );
00195             painter.drawRect( context.layoutUnitToPixelX( myPos.x() ),
00196                               context.layoutUnitToPixelY( myPos.y() ),
00197                               context.layoutUnitToPixelX( getWidth() ),
00198                               context.layoutUnitToPixelY( getHeight() ) );
00199         }
00200     }
00201 */
00202 }
00203 
00204 
00205 void TextElement::dispatchFontCommand( FontCommand* cmd )
00206 {
00207     cmd->addTextElement( this );
00208 }
00209 
00210 void TextElement::setCharStyle( CharStyle cs )
00211 {
00212     charStyle( cs );
00213     //formula()->changed();
00214 }
00215 
00216 void TextElement::setCharFamily( CharFamily cf )
00217 {
00218     charFamily( cf );
00219     //formula()->changed();
00220 }
00221 
00222 QChar TextElement::getRealCharacter(const ContextStyle& context)
00223 {
00224     if ( !isSymbol() ) {
00225         const FontStyle& fontStyle = context.fontStyle();
00226         const AlphaTable* alphaTable = fontStyle.alphaTable();
00227         if ( alphaTable != 0 ) {
00228 #warning "port it"                              
00229             //AlphaTableEntry ate = alphaTable->entry( character,
00230             //                                         charFamily(),
00231              //                                        charStyle() );
00232             //if ( ate.valid() ) {
00233             //    return ate.pos;
00234             //}
00235         }
00236         return character;
00237     }
00238     else {
00239         return getSymbolTable().character(character, charStyle());
00240     }
00241 }
00242 
00243 
00244 QFont TextElement::getFont(const ContextStyle& context)
00245 {
00246     if ( !isSymbol() ) {
00247         const FontStyle& fontStyle = context.fontStyle();
00248         const AlphaTable* alphaTable = fontStyle.alphaTable();
00249         if ( alphaTable != 0 ) {
00250 #warning "kde4: port it"
00251             //AlphaTableEntry ate = alphaTable->entry( character,
00252             //                                         charFamily(),
00253             //                                         charStyle() );
00254             //if ( ate.valid() ) {
00255             //    return ate.font;
00256             //}
00257         }
00258         QFont font;
00259 /*        if (getElementType() != 0) {
00260             font = getElementType()->getFont(context);
00261         }
00262         else {
00263             font = context.getDefaultFont();
00264         }*/
00265         switch ( charStyle() ) {
00266         case anyChar:
00267             break;
00268         case normalChar:
00269             font.setItalic( false );
00270             font.setBold( false );
00271             break;
00272         case boldChar:
00273             font.setItalic( false );
00274             font.setBold( true );
00275             break;
00276         case italicChar:
00277             font.setItalic( true );
00278             font.setBold( false );
00279             break;
00280         case boldItalicChar:
00281             font.setItalic( true );
00282             font.setBold( true );
00283             break;
00284         }
00285         return font;
00286     }
00287     return context.symbolTable().font( character, charStyle() );
00288 }
00289 
00290 
00291 void TextElement::setUpPainter(const ContextStyle& context, QPainter& painter)
00292 {
00293 /*    if (getElementType() != 0) {
00294         getElementType()->setUpPainter(context, painter);
00295     }
00296     else {
00297         painter.setPen(Qt::red);
00298     }*/
00299 }
00300 
00301 const SymbolTable& TextElement::getSymbolTable() const
00302 {
00303     static SymbolTable s;
00304     return s;
00305 }
00306 
00307 
00311 void TextElement::writeDom(QDomElement element)
00312 {
00313     BasicElement::writeDom(element);
00314     element.setAttribute("CHAR", QString(character));
00315     //QString s;
00316     //element.setAttribute("CHAR", s.sprintf( "#x%05X", character ) );
00317     if (symbol) element.setAttribute("SYMBOL", "3");
00318 
00319     switch ( charStyle() ) {
00320     case anyChar: break;
00321     case normalChar: element.setAttribute("STYLE", "normal"); break;
00322     case boldChar: element.setAttribute("STYLE", "bold"); break;
00323     case italicChar: element.setAttribute("STYLE", "italic"); break;
00324     case boldItalicChar: element.setAttribute("STYLE", "bolditalic"); break;
00325     }
00326 
00327     switch ( charFamily() ) {
00328     case normalFamily: element.setAttribute("FAMILY", "normal"); break;
00329     case scriptFamily: element.setAttribute("FAMILY", "script"); break;
00330     case frakturFamily: element.setAttribute("FAMILY", "fraktur"); break;
00331     case doubleStruckFamily: element.setAttribute("FAMILY", "doublestruck"); break;
00332     case anyFamily: break;
00333     }
00334 }
00335 
00340 bool TextElement::readAttributesFromDom(QDomElement element)
00341 {
00342     if (!BasicElement::readAttributesFromDom(element)) {
00343         return false;
00344     }
00345     QString charStr = element.attribute("CHAR");
00346     if(!charStr.isNull()) {
00347         character = charStr.at(0);
00348     }
00349     QString symbolStr = element.attribute("SYMBOL");
00350     if(!symbolStr.isNull()) {
00351         int symbolInt = symbolStr.toInt();
00352         if ( symbolInt == 1 ) {
00353             character = getSymbolTable().unicodeFromSymbolFont(character);
00354         }
00355         if ( symbolInt == 2 ) {
00356             switch ( character.unicode() ) {
00357             case 0x03D5: character = 0x03C6; break;
00358             case 0x03C6: character = 0x03D5; break;
00359             case 0x03Ba: character = 0x03BA; break;
00360             case 0x00B4: character = 0x2032; break;
00361             case 0x2215: character = 0x2244; break;
00362             case 0x00B7: character = 0x2022; break;
00363             case 0x1D574: character = 0x2111; break;
00364             case 0x1D579: character = 0x211C; break;
00365             case 0x2219: character = 0x22C5; break;
00366             case 0x2662: character = 0x26C4; break;
00367             case 0x220B: character = 0x220D; break;
00368             case 0x224C: character = 0x2245; break;
00369             case 0x03DB: character = 0x03C2; break;
00370             }
00371         }
00372         symbol = symbolInt != 0;
00373     }
00374 
00375     QString styleStr = element.attribute("STYLE");
00376     if ( styleStr == "normal" ) {
00377         charStyle( normalChar );
00378     }
00379     else if ( styleStr == "bold" ) {
00380         charStyle( boldChar );
00381     }
00382     else if ( styleStr == "italic" ) {
00383         charStyle( italicChar );
00384     }
00385     else if ( styleStr == "bolditalic" ) {
00386         charStyle( boldItalicChar );
00387     }
00388     else {
00389         charStyle( anyChar );
00390     }
00391 
00392     QString familyStr = element.attribute( "FAMILY" );
00393     if ( familyStr == "normal" ) {
00394         charFamily( normalFamily );
00395     }
00396     else if ( familyStr == "script" ) {
00397         charFamily( scriptFamily );
00398     }
00399     else if ( familyStr == "fraktur" ) {
00400         charFamily( frakturFamily );
00401     }
00402     else if ( familyStr == "doublestruck" ) {
00403         charFamily( doubleStruckFamily );
00404     }
00405     else {
00406         charFamily( anyFamily );
00407     }
00408 
00409     return true;
00410 }
00411 
00417 bool TextElement::readContentFromDom(QDomNode& node)
00418 {
00419     return BasicElement::readContentFromDom(node);
00420 }
00421 
00422 } // namespace KFormula

Généré le Wed Nov 22 23:41:01 2006 pour KPlato par  doxygen 1.5.1-p1