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 "cmstyle.h"
00028
00029
00030 KFORMULA_NAMESPACE_BEGIN
00031
00032
#include "cmmapping.cc"
00033
00034
bool CMStyle::init(
ContextStyle* context )
00035 {
00036
SymbolTable* st = symbolTable();
00037 st->
init( context );
00038
00039
SymbolTable::NameTable tempNames;
00040 fillNameTable( tempNames );
00041
00042 st->
initFont( cmbx10Map,
"cmbx10", tempNames );
00043 st->
initFont( cmex10Map,
"cmex10", tempNames );
00044 st->
initFont( cmmi10Map,
"cmmi10", tempNames );
00045 st->
initFont( cmr10Map,
"cmr10", tempNames );
00046 st->
initFont( cmsy10Map,
"cmsy10", tempNames );
00047 st->
initFont( msam10Map,
"msam10", tempNames );
00048 st->
initFont( msbm10Map,
"msbm10", tempNames );
00049
00050
return true;
00051 }
00052
00053
00054
const AlphaTable* CMStyle::alphaTable()
const
00055
{
00056
return &m_alphaTable;
00057 }
00058
00059
00060 Artwork* CMStyle::createArtwork( SymbolType type )
const
00061
{
00062
return new CMArtwork( type );
00063 }
00064
00065
00066 CMAlphaTable::CMAlphaTable()
00067 {
00068 }
00069
00070
00071
AlphaTableEntry CMAlphaTable::entry(
short pos,
00072 CharFamily family,
00073 CharStyle )
const
00074
{
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
AlphaTableEntry entry;
00093
switch( family ) {
00094
00095
case scriptFamily:
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
if ( ( pos >=
'A' ) && ( pos <=
'Z' ) ) {
00106 entry.
pos = pos;
00107 entry.
font =
QFont(
"cmsy10" );
00108 }
00109
break;
00110
case frakturFamily:
00111
break;
00112
case doubleStruckFamily:
00113
if ( ( pos >=
'A' ) && ( pos <=
'Z' ) ) {
00114 entry.
pos = pos;
00115 entry.
font =
QFont(
"msbm10" );
00116 }
00117
break;
00118
default:
00119
break;
00120 }
00121
return entry;
00122 }
00123
00124
00125
static const char cmex_LeftSquareBracket = 163;
00126
static const char cmex_RightSquareBracket = 164;
00127
static const char cmex_LeftCurlyBracket = 169;
00128
static const char cmex_RightCurlyBracket = 170;
00129
static const char cmex_LeftCornerBracket = 173;
00130
static const char cmex_RightCornerBracket = 174;
00131
static const char cmex_LeftRoundBracket = 161;
00132
static const char cmex_RightRoundBracket = 162;
00133
static const char cmex_SlashBracket = 177;
00134
static const char cmex_BackSlashBracket = 178;
00135
00136
00137
00138
00139
static const char cmex_Int = 90;
00140
static const char cmex_Sum = 88;
00141
static const char cmex_Prod = 89;
00142
00143
00144
00145
static short cmex_nextchar(
short ch )
00146 {
00147
switch ( ch ) {
00148
case 161:
return 179;
00149
case 162:
return 180;
00150
case 163:
return 104;
00151
case 164:
return 105;
00152
case 169:
return 110;
00153
case 170:
return 111;
00154
case 165:
return 106;
00155
case 166:
return 107;
00156
case 167:
return 108;
00157
case 168:
return 109;
00158
case 173:
return 68;
00159
case 174:
return 69;
00160
case 177:
return 46;
00161
case 178:
return 47;
00162
00163
case 179:
return 181;
00164
case 180:
return 182;
00165
case 104:
return 183;
00166
case 105:
return 184;
00167
case 110:
return 189;
00168
case 111:
return 190;
00169
case 106:
return 185;
00170
case 107:
return 186;
00171
case 108:
return 187;
00172
case 109:
return 188;
00173
case 68:
return 191;
00174
case 69:
return 192;
00175
case 46:
return 193;
00176
case 47:
return 194;
00177
00178
case 181:
return 195;
00179
case 182:
return 33;
00180
case 183:
return 34;
00181
case 184:
return 35;
00182
case 189:
return 40;
00183
case 190:
return 41;
00184
case 185:
return 36;
00185
case 186:
return 37;
00186
case 187:
return 38;
00187
case 188:
return 39;
00188
case 191:
return 42;
00189
case 192:
return 43;
00190
case 193:
return 44;
00191
case 194:
return 45;
00192 }
00193
return 0;
00194 }
00195
00196 CMArtwork::CMArtwork( SymbolType t )
00197 : Artwork( t ), cmChar( -1 )
00198 {
00199 }
00200
00201
00202
void CMArtwork::calcSizes(
const ContextStyle& style,
00203 ContextStyle::TextStyle tstyle,
00204 luPt parentSize )
00205 {
00206 setBaseline( -1 );
00207 cmChar = -1;
00208 luPt mySize = style.getAdjustedSize( tstyle );
00209
switch (getType()) {
00210
case LeftSquareBracket:
00211
if ( calcCMDelimiterSize( style, cmex_LeftSquareBracket,
00212 mySize, parentSize ) ) {
00213
return;
00214 }
00215 calcRoundBracket( style, leftSquareBracket, parentSize, mySize );
00216
break;
00217
case RightSquareBracket:
00218
if ( calcCMDelimiterSize( style, cmex_RightSquareBracket,
00219 mySize, parentSize ) ) {
00220
return;
00221 }
00222 calcRoundBracket( style, rightSquareBracket, parentSize, mySize );
00223
break;
00224
case LeftLineBracket:
00225 calcRoundBracket( style, leftLineBracket, parentSize, mySize );
00226 setWidth( getWidth()/2 );
00227
break;
00228
case RightLineBracket:
00229 calcRoundBracket( style, rightLineBracket, parentSize, mySize );
00230 setWidth( getWidth()/2 );
00231
break;
00232
case SlashBracket:
00233
if ( calcCMDelimiterSize( style, cmex_SlashBracket,
00234 mySize, parentSize ) ) {
00235
return;
00236 }
00237 calcLargest( style, cmex_SlashBracket, mySize );
00238
break;
00239
case BackSlashBracket:
00240
if ( calcCMDelimiterSize( style, cmex_BackSlashBracket,
00241 mySize, parentSize ) ) {
00242
return;
00243 }
00244 calcLargest( style, cmex_BackSlashBracket, mySize );
00245
break;
00246
case LeftCornerBracket:
00247
if ( calcCMDelimiterSize( style, cmex_LeftCornerBracket,
00248 mySize, parentSize ) ) {
00249
return;
00250 }
00251 calcLargest( style, cmex_LeftCornerBracket, mySize );
00252
break;
00253
case RightCornerBracket:
00254
if ( calcCMDelimiterSize( style, cmex_RightCornerBracket,
00255 mySize, parentSize ) ) {
00256
return;
00257 }
00258 calcLargest( style, cmex_RightCornerBracket, mySize );
00259
break;
00260
case LeftRoundBracket:
00261
if ( calcCMDelimiterSize( style, cmex_LeftRoundBracket,
00262 mySize, parentSize ) ) {
00263
return;
00264 }
00265 calcRoundBracket( style, leftRoundBracket, parentSize, mySize );
00266
break;
00267
case RightRoundBracket:
00268
if ( calcCMDelimiterSize( style, cmex_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 ( calcCMDelimiterSize( style, cmex_LeftCurlyBracket,
00281 mySize, parentSize ) ) {
00282
return;
00283 }
00284 calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize );
00285
break;
00286
case RightCurlyBracket:
00287
if ( calcCMDelimiterSize( style, cmex_RightCurlyBracket,
00288 mySize, parentSize ) ) {
00289
return;
00290 }
00291 calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize );
00292
break;
00293
case Integral:
00294 calcCharSize( style,
QFont(
"cmex10" ), mySize, cmex_Int );
00295
break;
00296
case Sum:
00297 calcCharSize( style,
QFont(
"cmex10" ), mySize, cmex_Sum );
00298
break;
00299
case Product:
00300 calcCharSize( style,
QFont(
"cmex10" ), mySize, cmex_Prod );
00301
break;
00302 }
00303 }
00304
00305
00306
void CMArtwork::calcSizes(
const ContextStyle& style,
00307 ContextStyle::TextStyle tstyle )
00308 {
00309 luPt mySize = style.getAdjustedSize( tstyle );
00310
switch (getType()) {
00311
case LeftLineBracket:
00312
case RightLineBracket:
00313 calcCharSize(style, mySize, 0x2223);
00314
break;
00315
default:
00316 Artwork::calcSizes( style, tstyle );
00317
break;
00318 }
00319 }
00320
00321
00322
void CMArtwork::draw(
QPainter& painter,
const LuPixelRect& r,
00323
const ContextStyle& style,
00324 ContextStyle::TextStyle tstyle,
00325
const LuPixelPoint& parentOrigin )
00326 {
00327 luPt mySize = style.getAdjustedSize( tstyle );
00328 luPixel myX = parentOrigin.x() + getX();
00329 luPixel myY = parentOrigin.y() + getY();
00330
if ( !
LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00331
return;
00332
00333 painter.setPen(style.getDefaultColor());
00334
00335
switch (getType()) {
00336
case LeftLineBracket:
00337
case RightLineBracket:
00338 drawCharacter(painter, style, myX, myY, mySize, 0x2223);
00339
break;
00340
default:
00341 Artwork::draw( painter, r, style, tstyle, parentOrigin );
00342
break;
00343 }
00344 }
00345
00346
00347
void CMArtwork::draw(
QPainter& painter,
const LuPixelRect& r,
00348
const ContextStyle& style, ContextStyle::TextStyle tstyle,
00349 luPt ,
const LuPixelPoint& origin)
00350 {
00351 luPt mySize = style.getAdjustedSize( tstyle );
00352 luPixel myX = origin.x() + getX();
00353 luPixel myY = origin.y() + getY();
00354
if ( !
LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00355
return;
00356
00357 painter.setPen(style.getDefaultColor());
00358
00359
switch (getType()) {
00360
case LeftSquareBracket:
00361
if ( cmChar != -1 ) {
00362 drawCMDelimiter( painter, style, myX, myY, mySize );
00363 }
00364
else {
00365 drawBigRoundBracket( painter, style, leftSquareBracket, myX, myY, mySize );
00366 }
00367
break;
00368
case RightSquareBracket:
00369
if ( cmChar != -1 ) {
00370 drawCMDelimiter( painter, style, myX, myY, mySize );
00371 }
00372
else {
00373 drawBigRoundBracket( painter, style, rightSquareBracket, myX, myY, mySize );
00374 }
00375
break;
00376
case LeftCurlyBracket:
00377
if ( cmChar != -1 ) {
00378 drawCMDelimiter( painter, style, myX, myY, mySize );
00379 }
00380
else {
00381 drawBigCurlyBracket( painter, style, leftCurlyBracket, myX, myY, mySize );
00382 }
00383
break;
00384
case RightCurlyBracket:
00385
if ( cmChar != -1 ) {
00386 drawCMDelimiter( painter, style, myX, myY, mySize );
00387 }
00388
else {
00389 drawBigCurlyBracket( painter, style, rightCurlyBracket, myX, myY, mySize );
00390 }
00391
break;
00392
case LeftLineBracket: {
00393 luPixel halfWidth = getWidth()/2;
00394 drawBigRoundBracket( painter, style, leftLineBracket,
00395 myX-halfWidth, myY, mySize );
00396 }
00397
break;
00398
case RightLineBracket: {
00399 luPixel halfWidth = getWidth()/2;
00400 drawBigRoundBracket( painter, style, rightLineBracket,
00401 myX-halfWidth, myY, mySize );
00402 }
00403
break;
00404
case SlashBracket:
00405
if ( cmChar != -1 ) {
00406 drawCMDelimiter( painter, style, myX, myY, mySize );
00407 }
00408
break;
00409
case BackSlashBracket:
00410
if ( cmChar != -1 ) {
00411 drawCMDelimiter( painter, style, myX, myY, mySize );
00412 }
00413
break;
00414
case LeftCornerBracket:
00415
if ( cmChar != -1 ) {
00416 drawCMDelimiter( painter, style, myX, myY, mySize );
00417 }
00418
else drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00419
break;
00420
case RightCornerBracket:
00421
if ( cmChar != -1 ) {
00422 drawCMDelimiter( painter, style, myX, myY, mySize );
00423 }
00424
else drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00425
break;
00426
case LeftRoundBracket:
00427
if ( cmChar != -1 ) {
00428 drawCMDelimiter( painter, style, myX, myY, mySize );
00429 }
00430
else {
00431 drawBigRoundBracket( painter, style, leftRoundBracket, myX, myY, mySize );
00432 }
00433
break;
00434
case RightRoundBracket:
00435
if ( cmChar != -1 ) {
00436 drawCMDelimiter( painter, style, myX, myY, mySize );
00437 }
00438
else {
00439 drawBigRoundBracket( painter, style, rightRoundBracket, myX, myY, mySize );
00440 }
00441
break;
00442
case EmptyBracket:
00443
break;
00444
case Integral:
00445 drawCharacter(painter, style,
QFont(
"cmex10" ), myX, myY, mySize, cmex_Int);
00446
break;
00447
case Sum:
00448 drawCharacter(painter, style,
QFont(
"cmex10" ), myX, myY, mySize, cmex_Sum);
00449
break;
00450
case Product:
00451 drawCharacter(painter, style,
QFont(
"cmex10" ), myX, myY, mySize, cmex_Prod);
00452
break;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 }
00463
00464
00465
bool CMArtwork::isNormalChar()
const
00466
{
00467
return Artwork::isNormalChar() && ( cmChar == -1 );
00468 }
00469
00470
double CMArtwork::slant()
const
00471
{
00472
if ( getType() == Integral ) {
00473
return 0.25;
00474 }
00475
return 0;
00476 }
00477
00478
bool CMArtwork::calcCMDelimiterSize(
const ContextStyle& context,
00479 uchar c,
00480 luPt fontSize,
00481 luPt parentSize )
00482 {
00483
QFont f(
"cmex10" );
00484 f.setPointSizeFloat( context.
layoutUnitPtToPt( fontSize ) );
00485
QFontMetrics fm( f );
00486
00487
for (
char i=1; c != 0; ++i ) {
00488
LuPixelRect bound = fm.boundingRect( c );
00489
00490 luPt height = context.
ptToLayoutUnitPt( bound.height() );
00491
if ( height >= parentSize ) {
00492 luPt width = context.
ptToLayoutUnitPt( fm.width( c ) );
00493 luPt baseline = context.
ptToLayoutUnitPt( -bound.top() );
00494
00495 cmChar = c;
00496
00497 setHeight( height );
00498 setWidth( width );
00499 setBaseline( baseline );
00500
00501
return true;
00502 }
00503 c = cmex_nextchar( c );
00504 }
00505
00506
00507
return false;
00508 }
00509
00510
00511
void CMArtwork::calcLargest(
const ContextStyle& context,
00512 uchar c, luPt fontSize )
00513 {
00514
QFont f(
"cmex10" );
00515 f.setPointSizeFloat( context.
layoutUnitPtToPt( fontSize ) );
00516
QFontMetrics fm( f );
00517
00518 cmChar = c;
00519
for ( ;; ) {
00520 c = cmex_nextchar( c );
00521
if ( c == 0 ) {
00522
break;
00523 }
00524 cmChar = c;
00525 }
00526
00527
LuPixelRect bound = fm.boundingRect( cmChar );
00528
00529 luPt height = context.
ptToLayoutUnitPt( bound.height() );
00530 luPt width = context.
ptToLayoutUnitPt( fm.width( cmChar ) );
00531 luPt baseline = context.
ptToLayoutUnitPt( -bound.top() );
00532
00533 setHeight( height );
00534 setWidth( width );
00535 setBaseline( baseline );
00536 }
00537
00538
00539
void CMArtwork::drawCMDelimiter(
QPainter& painter,
const ContextStyle& style,
00540 luPixel x, luPixel y,
00541 luPt height )
00542 {
00543
QFont f(
"cmex10" );
00544 f.setPointSizeFloat( style.layoutUnitToFontSize( height,
false ) );
00545
00546 painter.setFont( f );
00547 painter.drawText( style.layoutUnitToPixelX( x ),
00548 style.layoutUnitToPixelY( y + getBaseline() ),
00549
QString(
QChar( cmChar ) ) );
00550
00551
00552
#if 0
00553
QFontMetrics fm( f );
00554
LuPixelRect bound = fm.boundingRect( cmChar );
00555 painter.setBrush(Qt::NoBrush);
00556 painter.setPen(Qt::green);
00557 painter.drawRect( style.layoutUnitToPixelX( x ),
00558 style.layoutUnitToPixelY( y ),
00559 fm.width( cmChar ),
00560 bound.height() );
00561
#endif
00562
}
00563
00564
00565 KFORMULA_NAMESPACE_END