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, bool )
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& ,
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
00314
00315
00316
00317
00318 painter.setPen(style.getDefaultColor());
00319
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
00372 break;
00373 case BackSlashBracket:
00374
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
00418
00419
00420
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
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
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