00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 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 ) const
00112 {
00113 AlphaTableEntry entry;
00114
00115
00116 switch( family ) {
00117
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
00156
00157 static const char esstixseven_LeftLineBracket = 0x4b;
00158 static const char esstixseven_RightLineBracket = 0x4b;
00159
00160
00161
00162 static char esstixseven_nextchar( char ch )
00163 {
00164 switch ( ch ) {
00165
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
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
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
00242 break;
00243 case BackSlashBracket:
00244
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
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 , const LuPixelPoint& origin)
00309 {
00310 luPt mySize = style.getAdjustedSize( tstyle );
00311 luPixel myX = origin.x() + getX();
00312 luPixel myY = origin.y() + getY();
00313 if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00314 return;
00315
00316 painter.setPen(style.getDefaultColor());
00317
00318
00319 switch (getType()) {
00320 case LeftSquareBracket:
00321 if ( esstixChar != -1 ) {
00322 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00323 }
00324 else {
00325 drawBigRoundBracket( painter, style, leftSquareBracket, myX, myY, mySize );
00326 }
00327 break;
00328 case RightSquareBracket:
00329 if ( esstixChar != -1 ) {
00330 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00331 }
00332 else {
00333 drawBigRoundBracket( painter, style, rightSquareBracket, myX, myY, mySize );
00334 }
00335 break;
00336 case LeftCurlyBracket:
00337 if ( esstixChar != -1 ) {
00338 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00339 }
00340 else {
00341 drawBigCurlyBracket( painter, style, leftCurlyBracket, myX, myY, mySize );
00342 }
00343 break;
00344 case RightCurlyBracket:
00345 if ( esstixChar != -1 ) {
00346 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00347 }
00348 else {
00349 drawBigCurlyBracket( painter, style, rightCurlyBracket, myX, myY, mySize );
00350 }
00351 break;
00352 case LeftLineBracket:
00353 if ( esstixChar != -1 ) {
00354 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00355 }
00356 else {
00357 drawBigRoundBracket( painter, style, leftLineBracket, myX, myY, mySize );
00358 }
00359 break;
00360 case RightLineBracket:
00361 if ( esstixChar != -1 ) {
00362 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00363 }
00364 else {
00365 drawBigRoundBracket( painter, style, rightLineBracket, myX, myY, mySize );
00366 }
00367 break;
00368 case SlashBracket:
00369
00370 break;
00371 case BackSlashBracket:
00372
00373 break;
00374 case LeftCornerBracket:
00375 if ( esstixChar != -1 ) {
00376 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00377 }
00378 else drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00379 break;
00380 case RightCornerBracket:
00381 if ( esstixChar != -1 ) {
00382 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00383 }
00384 else drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00385 break;
00386 case LeftRoundBracket:
00387 if ( esstixChar != -1 ) {
00388 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00389 }
00390 else {
00391 drawBigRoundBracket( painter, style, leftRoundBracket, myX, myY, mySize );
00392 }
00393 break;
00394 case RightRoundBracket:
00395 if ( esstixChar != -1 ) {
00396 drawEsstixDelimiter( painter, style, myX, myY, mySize );
00397 }
00398 else {
00399 drawBigRoundBracket( painter, style, rightRoundBracket, myX, myY, mySize );
00400 }
00401 break;
00402 case EmptyBracket:
00403 break;
00404 case Integral:
00405 drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), integralChar);
00406 break;
00407 case Sum:
00408 drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), summationChar);
00409 break;
00410 case Product:
00411 drawCharacter(painter, style, myX, myY, qRound( 1.5*mySize ), productChar);
00412 break;
00413 }
00414
00415
00416
00417
00418
00419 }
00420
00421
00422 bool EsstixArtwork::isNormalChar() const
00423 {
00424 return Artwork::isNormalChar() && ( fontSizeFactor == 1 );
00425 }
00426
00427
00428 bool EsstixArtwork::calcEsstixDelimiterSize( const ContextStyle& context,
00429 char c,
00430 luPt fontSize,
00431 luPt parentSize )
00432 {
00433 QFont f( "esstixseven" );
00434
00435 for ( char i=1; c != 0; ++i ) {
00436
00437 f.setPointSizeFloat( context.layoutUnitPtToPt( i*fontSize ) );
00438 QFontMetrics fm( f );
00439 LuPixelRect bound = fm.boundingRect( c );
00440
00441 luPt height = context.ptToLayoutUnitPt( bound.height() );
00442 if ( height >= parentSize ) {
00443 luPt width = context.ptToLayoutUnitPt( fm.width( c ) );
00444 luPt baseline = context.ptToLayoutUnitPt( -bound.top() );
00445
00446 esstixChar = c;
00447 fontSizeFactor = i;
00448
00449 setHeight( height );
00450 setWidth( width );
00451 setBaseline( baseline );
00452
00453 return true;
00454 }
00455 c = esstixseven_nextchar( c );
00456 }
00457
00458
00459 return false;
00460 }
00461
00462
00463 void EsstixArtwork::drawEsstixDelimiter( QPainter& painter, const ContextStyle& style,
00464 luPixel x, luPixel y,
00465 luPt height )
00466 {
00467 QFont f( "esstixseven" );
00468 f.setPointSizeFloat( style.layoutUnitToFontSize( fontSizeFactor*height, false ) );
00469
00470 painter.setFont( f );
00471 painter.drawText( style.layoutUnitToPixelX( x ),
00472 style.layoutUnitToPixelY( y + getBaseline() ),
00473 QString( QChar( esstixChar ) ) );
00474 }
00475
00476
00477 KFORMULA_NAMESPACE_END