lib

esstixfontstyle.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Ulrich Kuettler <ulrich.kuettler@gmx.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <qpainter.h>
00021 #include <qpen.h>
00022 
00023 #include <kdebug.h>
00024 #include <klocale.h>
00025 
00026 #include "kformuladefs.h"
00027 #include "esstixfontstyle.h"
00028 
00029 
00030 KFORMULA_NAMESPACE_BEGIN
00031 
00032 #include "esstixfontmapping.cc"
00033 
00034 bool EsstixFontStyle::init( ContextStyle* context, bool /* install */ )
00035 {
00036     SymbolTable* st = symbolTable();
00037     st->init( context );
00038 
00039     SymbolTable::NameTable tempNames;
00040     fillNameTable( tempNames );
00041 
00042     st->initFont( esstixeightMap, "esstixeight", tempNames );
00043     st->initFont( esstixelevenMap, "esstixeleven", tempNames );
00044     st->initFont( esstixfifteenMap, "esstixfifteen", tempNames );
00045     st->initFont( esstixfiveMap, "esstixfive", tempNames );
00046     st->initFont( esstixfourMap, "esstixfour", tempNames );
00047     st->initFont( esstixfourteenMap, "esstixfourteen", tempNames );
00048     st->initFont( esstixnineMap, "esstixnine", tempNames );
00049     st->initFont( esstixoneMap, "esstixone", tempNames );
00050     st->initFont( esstixsevenMap, "esstixseven", tempNames );
00051     st->initFont( esstixseventeenMap, "esstixseventeen", tempNames );
00052     st->initFont( esstixsixMap, "esstixsix", tempNames );
00053     st->initFont( esstixsixteenMap, "esstixsixteen", tempNames );
00054     st->initFont( esstixtenMap, "esstixten", tempNames );
00055     st->initFont( esstixthirteenMap, "esstixthirteen", tempNames );
00056     st->initFont( esstixthreeMap, "esstixthree", tempNames );
00057     st->initFont( esstixtwelveMap, "esstixtwelve", tempNames );
00058     st->initFont( esstixtwoMap, "esstixtwo", tempNames );
00059 
00060     return true;
00061 }
00062 
00063 
00064 const AlphaTable* EsstixFontStyle::alphaTable() const
00065 {
00066     return &m_alphaTable;
00067 }
00068 
00069 
00070 Artwork* EsstixFontStyle::createArtwork( SymbolType type ) const
00071 {
00072     return new EsstixArtwork( type );
00073 }
00074 
00075 QStringList EsstixFontStyle::missingFonts()
00076 {
00077     QStringList missing;
00078 
00079     testFont( missing, "esstixeight" );
00080     testFont( missing, "esstixeleven" );
00081     testFont( missing, "esstixfifteen" );
00082     testFont( missing, "esstixfive" );
00083     testFont( missing, "esstixfour" );
00084     testFont( missing, "esstixfourteen" );
00085     testFont( missing, "esstixnine" );
00086     testFont( missing, "esstixone" );
00087     testFont( missing, "esstixseven" );
00088     testFont( missing, "esstixseventeen" );
00089     testFont( missing, "esstixsix" );
00090     testFont( missing, "esstixsixteen" );
00091     testFont( missing, "esstixten" );
00092     testFont( missing, "esstixthirteen" );
00093     testFont( missing, "esstixthree" );
00094     testFont( missing, "esstixtwelve" );
00095     testFont( missing, "esstixtwo" );
00096 
00097     return missing;
00098 }
00099 
00100 
00101 EsstixAlphaTable::EsstixAlphaTable()
00102     : script_font( "esstixthirteen" ),
00103       fraktur_font( "esstixfifteen" ),
00104       double_struck_font( "esstixfourteen" )
00105 {
00106 }
00107 
00108 
00109 AlphaTableEntry EsstixAlphaTable::entry( short pos,
00110                                          CharFamily family,
00111                                          CharStyle /*style*/ ) const
00112 {
00113     AlphaTableEntry entry;
00114 
00115     // This is very font specific.
00116     switch( family ) {
00117         //case normal:
00118     case scriptFamily:
00119         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00120              ( ( pos >= 'a' ) && ( pos <= 'z' ) ) ) {
00121             entry.pos = pos;
00122             entry.font = script_font;
00123         }
00124         break;
00125     case frakturFamily:
00126         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00127              ( ( pos >= 'a' ) && ( pos <= 'z' ) ) ) {
00128             entry.pos = pos;
00129             entry.font = fraktur_font;
00130         }
00131         break;
00132     case doubleStruckFamily:
00133         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00134              ( ( pos >= '0' ) && ( pos <= '9' ) ) ) {
00135             entry.pos = pos;
00136             entry.font = double_struck_font;
00137         }
00138         break;
00139     default:
00140         break;
00141     }
00142 
00143     return entry;
00144 }
00145 
00146 
00147 static const char esstixseven_LeftSquareBracket = 0x3f;
00148 static const char esstixseven_RightSquareBracket = 0x40;
00149 static const char esstixseven_LeftCurlyBracket = 0x41;
00150 static const char esstixseven_RightCurlyBracket = 0x42;
00151 static const char esstixseven_LeftCornerBracket = 0x43;
00152 static const char esstixseven_RightCornerBracket = 0x44;
00153 static const char esstixseven_LeftRoundBracket = 0x3d;
00154 static const char esstixseven_RightRoundBracket = 0x3e;
00155 //static const char esstixseven_SlashBracket = '/';
00156 //static const char esstixseven_BackSlashBracket = '\\';
00157 static const char esstixseven_LeftLineBracket = 0x4b;
00158 static const char esstixseven_RightLineBracket = 0x4b;
00159 
00160 
00161 // esstixseven is a special font with symbols in three sizes.
00162 static char esstixseven_nextchar( char ch )
00163 {
00164     switch ( ch ) {
00165         // small
00166     case 61: return 33;
00167     case 62: return 35;
00168     case 63: return 36;
00169     case 64: return 37;
00170     case 65: return 38;
00171     case 66: return 40;
00172     case 67: return 41;
00173     case 68: return 42;
00174     case 69: return 43;
00175     case 70: return 44;
00176     case 75: return 45;
00177     case 76: return 47;
00178 
00179         // middle
00180     case 33: return 48;
00181     case 35: return 49;
00182     case 36: return 50;
00183     case 37: return 51;
00184     case 38: return 52;
00185     case 40: return 53;
00186     case 41: return 54;
00187     case 42: return 55;
00188     case 43: return 56;
00189     case 44: return 57;
00190     case 45: return 58;
00191     case 46: return 59;
00192     case 47: return 60;
00193     }
00194     return 0;
00195 }
00196 
00197 EsstixArtwork::EsstixArtwork( SymbolType t )
00198     : Artwork( t ), esstixChar( -1 )
00199 {
00200 }
00201 
00202 
00203 void EsstixArtwork::calcSizes( const ContextStyle& style,
00204                                ContextStyle::TextStyle tstyle,
00205                                luPt parentSize )
00206 {
00207     setBaseline( -1 );
00208     esstixChar = -1;
00209     luPt mySize = style.getAdjustedSize( tstyle );
00210     //const SymbolTable& symbolTable = style.symbolTable();
00211     switch (getType()) {
00212     case LeftSquareBracket:
00213         if ( calcEsstixDelimiterSize( style, esstixseven_LeftSquareBracket,
00214                                       mySize, parentSize ) ) {
00215             return;
00216         }
00217         calcRoundBracket( style, leftSquareBracket, parentSize, mySize );
00218         break;
00219     case RightSquareBracket:
00220         if ( calcEsstixDelimiterSize( style, esstixseven_RightSquareBracket,
00221                                       mySize, parentSize ) ) {
00222             return;
00223         }
00224         calcRoundBracket( style, rightSquareBracket, parentSize, mySize );
00225         break;
00226     case LeftLineBracket:
00227         if ( calcEsstixDelimiterSize( style, esstixseven_LeftLineBracket,
00228                                       mySize, parentSize ) ) {
00229             return;
00230         }
00231         calcRoundBracket( style, leftLineBracket, parentSize, mySize );
00232         break;
00233     case RightLineBracket:
00234         if ( calcEsstixDelimiterSize( style, esstixseven_RightLineBracket,
00235                                       mySize, parentSize ) ) {
00236             return;
00237         }
00238         calcRoundBracket( style, rightLineBracket, parentSize, mySize );
00239         break;
00240     case SlashBracket:
00241         //calcCharSize(style, mySize, '/');
00242         break;
00243     case BackSlashBracket:
00244         //calcCharSize(style, mySize, '\\');
00245         break;
00246     case LeftCornerBracket:
00247         if ( calcEsstixDelimiterSize( style, esstixseven_LeftCornerBracket,
00248                                       mySize, parentSize ) ) {
00249             return;
00250         }
00251         calcCharSize(style, mySize, leftAngleBracketChar);
00252         break;
00253     case RightCornerBracket:
00254         if ( calcEsstixDelimiterSize( style, esstixseven_RightCornerBracket,
00255                                       mySize, parentSize ) ) {
00256             return;
00257         }
00258         calcCharSize(style, mySize, rightAngleBracketChar);
00259         break;
00260     case LeftRoundBracket:
00261         if ( calcEsstixDelimiterSize( style, esstixseven_LeftRoundBracket,
00262                                       mySize, parentSize ) ) {
00263             return;
00264         }
00265         calcRoundBracket( style, leftRoundBracket, parentSize, mySize );
00266         break;
00267     case RightRoundBracket:
00268         if ( calcEsstixDelimiterSize( style, esstixseven_RightRoundBracket,
00269                                       mySize, parentSize ) ) {
00270             return;
00271         }
00272         calcRoundBracket( style, rightRoundBracket, parentSize, mySize );
00273         break;
00274     case EmptyBracket:
00275         setHeight(parentSize);
00276         //setWidth(style.getEmptyRectWidth());
00277         setWidth(0);
00278         break;
00279     case LeftCurlyBracket:
00280         if ( calcEsstixDelimiterSize( style, esstixseven_LeftCurlyBracket,
00281                                       mySize, parentSize ) ) {
00282             return;
00283         }
00284         calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize );
00285         break;
00286     case RightCurlyBracket:
00287         if ( calcEsstixDelimiterSize( style, esstixseven_RightCurlyBracket,
00288                                       mySize, parentSize ) ) {
00289             return;
00290         }
00291         calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize );
00292         break;
00293     case Integral:
00294         calcCharSize( style, qRound( 1.5*mySize ), integralChar );
00295         break;
00296     case Sum:
00297         calcCharSize( style, qRound( 1.5*mySize ), summationChar );
00298         break;
00299     case Product:
00300         calcCharSize( style, qRound( 1.5*mySize ), productChar );
00301         break;
00302     }
00303 }
00304 
00305 
00306 void EsstixArtwork::draw(QPainter& painter, const LuPixelRect& /*r*/,
00307                          const ContextStyle& style, ContextStyle::TextStyle tstyle,
00308                          luPt /*parentSize*/, const LuPixelPoint& origin)
00309 {
00310     luPt mySize = style.getAdjustedSize( tstyle );
00311     luPixel myX = origin.x() + getX();
00312     luPixel myY = origin.y() + getY();
00313     /*
00314     if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00315         return;
00316     */
00317 
00318     painter.setPen(style.getDefaultColor());
00319     //const SymbolTable& symbolTable = style.symbolTable();
00320 
00321     switch (getType()) {
00322     case LeftSquareBracket:
00323         if ( esstixChar != -1 ) {
00324             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00325         }
00326         else {
00327             drawBigRoundBracket( painter, style, leftSquareBracket, myX, myY, mySize );
00328         }
00329         break;
00330     case RightSquareBracket:
00331         if ( esstixChar != -1 ) {
00332             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00333         }
00334         else {
00335             drawBigRoundBracket( painter, style, rightSquareBracket, myX, myY, mySize );
00336         }
00337         break;
00338     case LeftCurlyBracket:
00339         if ( esstixChar != -1 ) {
00340             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00341         }
00342         else {
00343             drawBigCurlyBracket( painter, style, leftCurlyBracket, myX, myY, mySize );
00344         }
00345         break;
00346     case RightCurlyBracket:
00347         if ( esstixChar != -1 ) {
00348             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00349         }
00350         else {
00351             drawBigCurlyBracket( painter, style, rightCurlyBracket, myX, myY, mySize );
00352         }
00353         break;
00354     case LeftLineBracket:
00355         if ( esstixChar != -1 ) {
00356             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00357         }
00358         else {
00359             drawBigRoundBracket( painter, style, leftLineBracket, myX, myY, mySize );
00360         }
00361         break;
00362     case RightLineBracket:
00363         if ( esstixChar != -1 ) {
00364             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00365         }
00366         else {
00367             drawBigRoundBracket( painter, style, rightLineBracket, myX, myY, mySize );
00368         }
00369         break;
00370     case SlashBracket:
00371         //drawCharacter(painter, style, myX, myY, mySize, '/');
00372         break;
00373     case BackSlashBracket:
00374         //drawCharacter(painter, style, myX, myY, mySize, '\\');
00375         break;
00376     case LeftCornerBracket:
00377         if ( esstixChar != -1 ) {
00378             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00379         }
00380         else drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00381         break;
00382     case RightCornerBracket:
00383         if ( esstixChar != -1 ) {
00384             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00385         }
00386         else drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00387         break;
00388     case LeftRoundBracket:
00389         if ( esstixChar != -1 ) {
00390             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00391         }
00392         else {
00393             drawBigRoundBracket( painter, style, leftRoundBracket, myX, myY, mySize );
00394         }
00395         break;
00396     case RightRoundBracket:
00397         if ( esstixChar != -1 ) {
00398             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00399         }
00400         else {
00401             drawBigRoundBracket( painter, style, rightRoundBracket, myX, myY, mySize );
00402         }
00403         break;
00404     case EmptyBracket:
00405         break;
00406     case Integral:
00407         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), integralChar);
00408         break;
00409     case Sum:
00410         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), summationChar);
00411         break;
00412     case Product:
00413         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), productChar);
00414         break;
00415     }
00416 
00417     // debug
00418     //painter.setBrush(Qt::NoBrush);
00419     //painter.setPen(Qt::green);
00420     //painter.drawRect(myX, myY, getWidth(), getHeight());
00421 }
00422 
00423 
00424 bool EsstixArtwork::isNormalChar() const
00425 {
00426     return Artwork::isNormalChar() && ( fontSizeFactor == 1 );
00427 }
00428 
00429 
00430 bool EsstixArtwork::calcEsstixDelimiterSize( const ContextStyle& context,
00431                                              char c,
00432                                              luPt fontSize,
00433                                              luPt parentSize )
00434 {
00435     QFont f( "esstixseven" );
00436 
00437     for ( char i=1; c != 0; ++i ) {
00438         //f.setPointSizeFloat( context.layoutUnitToFontSize( i*fontSize, false ) );
00439         f.setPointSizeFloat( context.layoutUnitPtToPt( i*fontSize ) );
00440         QFontMetrics fm( f );
00441         LuPixelRect bound = fm.boundingRect( c );
00442 
00443         luPt height = context.ptToLayoutUnitPt( bound.height() );
00444         if ( height >= parentSize ) {
00445             luPt width = context.ptToLayoutUnitPt( fm.width( c ) );
00446             luPt baseline = context.ptToLayoutUnitPt( -bound.top() );
00447 
00448             esstixChar = c;
00449             fontSizeFactor = i;
00450 
00451             setHeight( height );
00452             setWidth( width );
00453             setBaseline( baseline );
00454 
00455             return true;
00456         }
00457         c = esstixseven_nextchar( c );
00458     }
00459 
00460     // Build it up from pieces.
00461     return false;
00462 }
00463 
00464 
00465 void EsstixArtwork::drawEsstixDelimiter( QPainter& painter, const ContextStyle& style,
00466                                          luPixel x, luPixel y,
00467                                          luPt height )
00468 {
00469     QFont f( "esstixseven" );
00470     f.setPointSizeFloat( style.layoutUnitToFontSize( fontSizeFactor*height, false ) );
00471 
00472     painter.setFont( f );
00473     painter.drawText( style.layoutUnitToPixelX( x ),
00474                       style.layoutUnitToPixelY( y + getBaseline() ),
00475                       QString( QChar( esstixChar ) ) );
00476 }
00477 
00478 
00479 KFORMULA_NAMESPACE_END
KDE Home | KDE Accessibility Home | Description of Access Keys