lib Library API Documentation

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., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, 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 )
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 
00076 EsstixAlphaTable::EsstixAlphaTable()
00077     : script_font( "esstixthirteen" ),
00078       fraktur_font( "esstixfifteen" ),
00079       double_struck_font( "esstixfourteen" )
00080 {
00081 }
00082 
00083 
00084 AlphaTableEntry EsstixAlphaTable::entry( short pos,
00085                                          CharFamily family,
00086                                          CharStyle /*style*/ ) const
00087 {
00088     AlphaTableEntry entry;
00089 
00090     // This is very font specific.
00091     switch( family ) {
00092         //case normal:
00093     case scriptFamily:
00094         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00095              ( ( pos >= 'a' ) && ( pos <= 'z' ) ) ) {
00096             entry.pos = pos;
00097             entry.font = script_font;
00098         }
00099         break;
00100     case frakturFamily:
00101         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00102              ( ( pos >= 'a' ) && ( pos <= 'z' ) ) ) {
00103             entry.pos = pos;
00104             entry.font = fraktur_font;
00105         }
00106         break;
00107     case doubleStruckFamily:
00108         if ( ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) ||
00109              ( ( pos >= '0' ) && ( pos <= '9' ) ) ) {
00110             entry.pos = pos;
00111             entry.font = double_struck_font;
00112         }
00113         break;
00114     default:
00115         break;
00116     }
00117 
00118     return entry;
00119 }
00120 
00121 
00122 static const char esstixseven_LeftSquareBracket = 0x3f;
00123 static const char esstixseven_RightSquareBracket = 0x40;
00124 static const char esstixseven_LeftCurlyBracket = 0x41;
00125 static const char esstixseven_RightCurlyBracket = 0x42;
00126 static const char esstixseven_LeftCornerBracket = 0x43;
00127 static const char esstixseven_RightCornerBracket = 0x44;
00128 static const char esstixseven_LeftRoundBracket = 0x3d;
00129 static const char esstixseven_RightRoundBracket = 0x3e;
00130 //static const char esstixseven_SlashBracket = '/';
00131 //static const char esstixseven_BackSlashBracket = '\\';
00132 static const char esstixseven_LeftLineBracket = 0x4b;
00133 static const char esstixseven_RightLineBracket = 0x4b;
00134 
00135 
00136 // esstixseven is a special font with symbols in three sizes.
00137 static char esstixseven_nextchar( char ch )
00138 {
00139     switch ( ch ) {
00140         // small
00141     case 61: return 33;
00142     case 62: return 35;
00143     case 63: return 36;
00144     case 64: return 37;
00145     case 65: return 38;
00146     case 66: return 40;
00147     case 67: return 41;
00148     case 68: return 42;
00149     case 69: return 43;
00150     case 70: return 44;
00151     case 75: return 45;
00152     case 76: return 47;
00153 
00154         // middle
00155     case 33: return 48;
00156     case 35: return 49;
00157     case 36: return 50;
00158     case 37: return 51;
00159     case 38: return 52;
00160     case 40: return 53;
00161     case 41: return 54;
00162     case 42: return 55;
00163     case 43: return 56;
00164     case 44: return 57;
00165     case 45: return 58;
00166     case 46: return 59;
00167     case 47: return 60;
00168     }
00169     return 0;
00170 }
00171 
00172 EsstixArtwork::EsstixArtwork( SymbolType t )
00173     : Artwork( t ), esstixChar( -1 )
00174 {
00175 }
00176 
00177 
00178 void EsstixArtwork::calcSizes( const ContextStyle& style,
00179                                ContextStyle::TextStyle tstyle,
00180                                luPt parentSize )
00181 {
00182     setBaseline( -1 );
00183     esstixChar = -1;
00184     luPt mySize = style.getAdjustedSize( tstyle );
00185     //const SymbolTable& symbolTable = style.symbolTable();
00186     switch (getType()) {
00187     case LeftSquareBracket:
00188         if ( calcEsstixDelimiterSize( style, esstixseven_LeftSquareBracket,
00189                                       mySize, parentSize ) ) {
00190             return;
00191         }
00192         calcRoundBracket( style, leftSquareBracket, parentSize, mySize );
00193         break;
00194     case RightSquareBracket:
00195         if ( calcEsstixDelimiterSize( style, esstixseven_RightSquareBracket,
00196                                       mySize, parentSize ) ) {
00197             return;
00198         }
00199         calcRoundBracket( style, rightSquareBracket, parentSize, mySize );
00200         break;
00201     case LeftLineBracket:
00202         if ( calcEsstixDelimiterSize( style, esstixseven_LeftLineBracket,
00203                                       mySize, parentSize ) ) {
00204             return;
00205         }
00206         calcRoundBracket( style, leftLineBracket, parentSize, mySize );
00207         break;
00208     case RightLineBracket:
00209         if ( calcEsstixDelimiterSize( style, esstixseven_RightLineBracket,
00210                                       mySize, parentSize ) ) {
00211             return;
00212         }
00213         calcRoundBracket( style, rightLineBracket, parentSize, mySize );
00214         break;
00215     case SlashBracket:
00216         //calcCharSize(style, mySize, '/');
00217         break;
00218     case BackSlashBracket:
00219         //calcCharSize(style, mySize, '\\');
00220         break;
00221     case LeftCornerBracket:
00222         if ( calcEsstixDelimiterSize( style, esstixseven_LeftCornerBracket,
00223                                       mySize, parentSize ) ) {
00224             return;
00225         }
00226         calcCharSize(style, mySize, leftAngleBracketChar);
00227         break;
00228     case RightCornerBracket:
00229         if ( calcEsstixDelimiterSize( style, esstixseven_RightCornerBracket,
00230                                       mySize, parentSize ) ) {
00231             return;
00232         }
00233         calcCharSize(style, mySize, rightAngleBracketChar);
00234         break;
00235     case LeftRoundBracket:
00236         if ( calcEsstixDelimiterSize( style, esstixseven_LeftRoundBracket,
00237                                       mySize, parentSize ) ) {
00238             return;
00239         }
00240         calcRoundBracket( style, leftRoundBracket, parentSize, mySize );
00241         break;
00242     case RightRoundBracket:
00243         if ( calcEsstixDelimiterSize( style, esstixseven_RightRoundBracket,
00244                                       mySize, parentSize ) ) {
00245             return;
00246         }
00247         calcRoundBracket( style, rightRoundBracket, parentSize, mySize );
00248         break;
00249     case EmptyBracket:
00250         setHeight(parentSize);
00251         //setWidth(style.getEmptyRectWidth());
00252         setWidth(0);
00253         break;
00254     case LeftCurlyBracket:
00255         if ( calcEsstixDelimiterSize( style, esstixseven_LeftCurlyBracket,
00256                                       mySize, parentSize ) ) {
00257             return;
00258         }
00259         calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize );
00260         break;
00261     case RightCurlyBracket:
00262         if ( calcEsstixDelimiterSize( style, esstixseven_RightCurlyBracket,
00263                                       mySize, parentSize ) ) {
00264             return;
00265         }
00266         calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize );
00267         break;
00268     case Integral:
00269         calcCharSize( style, qRound( 1.5*mySize ), integralChar );
00270         break;
00271     case Sum:
00272         calcCharSize( style, qRound( 1.5*mySize ), summationChar );
00273         break;
00274     case Product:
00275         calcCharSize( style, qRound( 1.5*mySize ), productChar );
00276         break;
00277     }
00278 }
00279 
00280 
00281 void EsstixArtwork::draw(QPainter& painter, const LuPixelRect& r,
00282                          const ContextStyle& style, ContextStyle::TextStyle tstyle,
00283                          luPt /*parentSize*/, const LuPixelPoint& origin)
00284 {
00285     luPt mySize = style.getAdjustedSize( tstyle );
00286     luPixel myX = origin.x() + getX();
00287     luPixel myY = origin.y() + getY();
00288     if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00289         return;
00290 
00291     painter.setPen(style.getDefaultColor());
00292     //const SymbolTable& symbolTable = style.symbolTable();
00293 
00294     switch (getType()) {
00295     case LeftSquareBracket:
00296         if ( esstixChar != -1 ) {
00297             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00298         }
00299         else {
00300             drawBigRoundBracket( painter, style, leftSquareBracket, myX, myY, mySize );
00301         }
00302         break;
00303     case RightSquareBracket:
00304         if ( esstixChar != -1 ) {
00305             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00306         }
00307         else {
00308             drawBigRoundBracket( painter, style, rightSquareBracket, myX, myY, mySize );
00309         }
00310         break;
00311     case LeftCurlyBracket:
00312         if ( esstixChar != -1 ) {
00313             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00314         }
00315         else {
00316             drawBigCurlyBracket( painter, style, leftCurlyBracket, myX, myY, mySize );
00317         }
00318         break;
00319     case RightCurlyBracket:
00320         if ( esstixChar != -1 ) {
00321             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00322         }
00323         else {
00324             drawBigCurlyBracket( painter, style, rightCurlyBracket, myX, myY, mySize );
00325         }
00326         break;
00327     case LeftLineBracket:
00328         if ( esstixChar != -1 ) {
00329             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00330         }
00331         else {
00332             drawBigRoundBracket( painter, style, leftLineBracket, myX, myY, mySize );
00333         }
00334         break;
00335     case RightLineBracket:
00336         if ( esstixChar != -1 ) {
00337             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00338         }
00339         else {
00340             drawBigRoundBracket( painter, style, rightLineBracket, myX, myY, mySize );
00341         }
00342         break;
00343     case SlashBracket:
00344         //drawCharacter(painter, style, myX, myY, mySize, '/');
00345         break;
00346     case BackSlashBracket:
00347         //drawCharacter(painter, style, myX, myY, mySize, '\\');
00348         break;
00349     case LeftCornerBracket:
00350         if ( esstixChar != -1 ) {
00351             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00352         }
00353         else drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00354         break;
00355     case RightCornerBracket:
00356         if ( esstixChar != -1 ) {
00357             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00358         }
00359         else drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00360         break;
00361     case LeftRoundBracket:
00362         if ( esstixChar != -1 ) {
00363             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00364         }
00365         else {
00366             drawBigRoundBracket( painter, style, leftRoundBracket, myX, myY, mySize );
00367         }
00368         break;
00369     case RightRoundBracket:
00370         if ( esstixChar != -1 ) {
00371             drawEsstixDelimiter( painter, style, myX, myY, mySize );
00372         }
00373         else {
00374             drawBigRoundBracket( painter, style, rightRoundBracket, myX, myY, mySize );
00375         }
00376         break;
00377     case EmptyBracket:
00378         break;
00379     case Integral:
00380         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), integralChar);
00381         break;
00382     case Sum:
00383         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), summationChar);
00384         break;
00385     case Product:
00386         drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), productChar);
00387         break;
00388     }
00389 
00390     // debug
00391     //painter.setBrush(Qt::NoBrush);
00392     //painter.setPen(Qt::green);
00393     //painter.drawRect(myX, myY, getWidth(), getHeight());
00394 }
00395 
00396 
00397 bool EsstixArtwork::isNormalChar() const
00398 {
00399     return Artwork::isNormalChar() && ( fontSizeFactor == 1 );
00400 }
00401 
00402 
00403 bool EsstixArtwork::calcEsstixDelimiterSize( const ContextStyle& context,
00404                                              char c,
00405                                              luPt fontSize,
00406                                              luPt parentSize )
00407 {
00408     QFont f( "esstixseven" );
00409 
00410     for ( char i=1; c != 0; ++i ) {
00411         //f.setPointSizeFloat( context.layoutUnitToFontSize( i*fontSize, false ) );
00412         f.setPointSizeFloat( context.layoutUnitPtToPt( i*fontSize ) );
00413         QFontMetrics fm( f );
00414         LuPixelRect bound = fm.boundingRect( c );
00415 
00416         luPt height = context.ptToLayoutUnitPt( bound.height() );
00417         if ( height >= parentSize ) {
00418             luPt width = context.ptToLayoutUnitPt( fm.width( c ) );
00419             luPt baseline = context.ptToLayoutUnitPt( -bound.top() );
00420 
00421             esstixChar = c;
00422             fontSizeFactor = i;
00423 
00424             setHeight( height );
00425             setWidth( width );
00426             setBaseline( baseline );
00427 
00428             return true;
00429         }
00430         c = esstixseven_nextchar( c );
00431     }
00432 
00433     // Build it up from pieces.
00434     return false;
00435 }
00436 
00437 
00438 void EsstixArtwork::drawEsstixDelimiter( QPainter& painter, const ContextStyle& style,
00439                                          luPixel x, luPixel y,
00440                                          luPt height )
00441 {
00442     QFont f( "esstixseven" );
00443     f.setPointSizeFloat( style.layoutUnitToFontSize( fontSizeFactor*height, false ) );
00444 
00445     painter.setFont( f );
00446     painter.drawText( style.layoutUnitToPixelX( x ),
00447                       style.layoutUnitToPixelY( y + getBaseline() ),
00448                       QString( QChar( esstixChar ) ) );
00449 }
00450 
00451 
00452 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 Sun Mar 20 14:25:23 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003