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 "fontstyle.h"
00024
00025
00026 KFORMULA_NAMESPACE_BEGIN
00027
00028
#include "unicodenames.cc"
00029
00030
void FontStyle::fillNameTable(
SymbolTable::NameTable& names )
00031 {
00032
for (
int i=0; nameTable[i].unicode != 0; ++i ) {
00033 names[
QChar( nameTable[i].unicode )] = nameTable[i].name;
00034 }
00035 }
00036
00037
00038
00039
00040
const QChar leftRoundBracket[] = {
00041 0xF8EB,
00042 0xF8ED,
00043 0xF8EC
00044 };
00045
const QChar leftSquareBracket[] = {
00046 0xF8EE,
00047 0xF8F0,
00048 0xF8EF
00049 };
00050
const QChar leftCurlyBracket[] = {
00051 0xF8F1,
00052 0xF8F3,
00053 0xF8F4,
00054 0xF8F2
00055 };
00056
00057
const QChar leftLineBracket[] = {
00058 0xF8EF,
00059 0xF8EF,
00060 0xF8EF
00061 };
00062
const QChar rightLineBracket[] = {
00063 0xF8FA,
00064 0xF8FA,
00065 0xF8FA
00066 };
00067
00068
const QChar rightRoundBracket[] = {
00069 0xF8F6,
00070 0xF8F8,
00071 0xF8F7
00072 };
00073
const QChar rightSquareBracket[] = {
00074 0xF8F9,
00075 0xF8FB,
00076 0xF8FA
00077 };
00078
const QChar rightCurlyBracket[] = {
00079 0xF8FC,
00080 0xF8FE,
00081 0xF8F4,
00082 0xF8FD
00083 };
00084
00085
00086 Artwork::Artwork(SymbolType t)
00087 : baseline( -1 ), type(t)
00088 {
00089 }
00090
00091
00092
void Artwork::calcSizes(
const ContextStyle& style,
00093 ContextStyle::TextStyle tstyle )
00094 {
00095 luPt mySize = style.getAdjustedSize( tstyle );
00096
switch (type) {
00097
case LeftSquareBracket:
00098 calcCharSize(style, mySize, leftSquareBracketChar);
00099
break;
00100
case RightSquareBracket:
00101 calcCharSize(style, mySize, rightSquareBracketChar);
00102
break;
00103
case LeftLineBracket:
00104
case RightLineBracket:
00105 calcCharSize(style, mySize, verticalLineChar);
00106
break;
00107
case SlashBracket:
00108 calcCharSize(style, mySize, slashChar);
00109
break;
00110
case BackSlashBracket:
00111 calcCharSize(style, mySize, backSlashChar);
00112
break;
00113
case LeftCornerBracket:
00114 calcCharSize(style, mySize, leftAngleBracketChar);
00115
break;
00116
case RightCornerBracket:
00117 calcCharSize(style, mySize, rightAngleBracketChar);
00118
break;
00119
case LeftRoundBracket:
00120 calcCharSize(style, mySize, leftParenthesisChar);
00121
break;
00122
case RightRoundBracket:
00123 calcCharSize(style, mySize, rightParenthesisChar);
00124
break;
00125
case EmptyBracket:
00126
00127 setHeight(0);
00128
00129 setWidth(0);
00130
break;
00131
case LeftCurlyBracket:
00132 calcCharSize(style, mySize, leftCurlyBracketChar);
00133
break;
00134
case RightCurlyBracket:
00135 calcCharSize(style, mySize, rightCurlyBracketChar);
00136
break;
00137
case Integral:
00138
case Sum:
00139
case Product:
00140
break;
00141 }
00142 }
00143
00144
00145
void Artwork::draw(
QPainter& painter,
const LuPixelRect& r,
00146
const ContextStyle& style, ContextStyle::TextStyle tstyle,
00147
const LuPixelPoint& parentOrigin)
00148 {
00149 luPt mySize = style.getAdjustedSize( tstyle );
00150 luPixel myX = parentOrigin.x() + getX();
00151 luPixel myY = parentOrigin.y() + getY();
00152
if ( !
LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00153
return;
00154
00155 painter.setPen(style.getDefaultColor());
00156
00157
switch (type) {
00158
case LeftSquareBracket:
00159 drawCharacter(painter, style, myX, myY, mySize, leftSquareBracketChar);
00160
break;
00161
case RightSquareBracket:
00162 drawCharacter(painter, style, myX, myY, mySize, rightSquareBracketChar);
00163
break;
00164
case LeftCurlyBracket:
00165 drawCharacter(painter, style, myX, myY, mySize, leftCurlyBracketChar);
00166
break;
00167
case RightCurlyBracket:
00168 drawCharacter(painter, style, myX, myY, mySize, rightCurlyBracketChar);
00169
break;
00170
case LeftLineBracket:
00171
case RightLineBracket:
00172 drawCharacter(painter, style, myX, myY, mySize, verticalLineChar);
00173
break;
00174
case SlashBracket:
00175 drawCharacter(painter, style, myX, myY, mySize, slashChar);
00176
break;
00177
case BackSlashBracket:
00178 drawCharacter(painter, style, myX, myY, mySize, backSlashChar);
00179
break;
00180
case LeftCornerBracket:
00181 drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00182
break;
00183
case RightCornerBracket:
00184 drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00185
break;
00186
case LeftRoundBracket:
00187 drawCharacter(painter, style, myX, myY, mySize, leftParenthesisChar);
00188
break;
00189
case RightRoundBracket:
00190 drawCharacter(painter, style, myX, myY, mySize, rightParenthesisChar);
00191
break;
00192
case EmptyBracket:
00193
break;
00194
case Integral:
00195
case Sum:
00196
case Product:
00197
break;
00198 }
00199 }
00200
00201
00202
void Artwork::calcCharSize(
const ContextStyle& style, luPt height,
QChar ch )
00203 {
00204
00205 uchar c = style.symbolTable().character( ch );
00206
QFont f = style.symbolTable().font( ch );
00207 calcCharSize( style, f, height, c );
00208 }
00209
00210
00211
void Artwork::drawCharacter(
QPainter& painter,
const ContextStyle& style,
00212 luPixel x, luPixel y,
00213 luPt height,
QChar ch )
00214 {
00215 uchar c = style.symbolTable().character( ch );
00216
QFont f = style.symbolTable().font( ch );
00217 drawCharacter( painter, style, f, x, y, height, c );
00218 }
00219
00220
00221
void Artwork::calcCharSize(
const ContextStyle& style,
QFont f,
00222 luPt height, uchar c )
00223 {
00224 f.setPointSizeFloat( style.layoutUnitPtToPt( height ) );
00225
00226
QFontMetrics fm(f);
00227 setWidth( style.ptToLayoutUnitPt( fm.width( c ) ) );
00228
LuPixelRect bound = fm.boundingRect( c );
00229 setHeight( style.ptToLayoutUnitPt( bound.height() ) );
00230 setBaseline( style.ptToLayoutUnitPt( -bound.top() ) );
00231 }
00232
00233
00234
void Artwork::drawCharacter(
QPainter& painter,
const ContextStyle& style,
00235
QFont f,
00236 luPixel x, luPixel y, luPt height, uchar c )
00237 {
00238 f.setPointSizeFloat( style.layoutUnitToFontSize( height,
false ) );
00239
00240 painter.setFont( f );
00241 painter.drawText( style.layoutUnitToPixelX( x ),
00242 style.layoutUnitToPixelY( y+getBaseline() ),
00243
QString(
QChar( c ) ) );
00244 }
00245
00246
00247
void Artwork::calcRoundBracket(
const ContextStyle& style,
const QChar chars[],
00248 luPt height, luPt charHeight )
00249 {
00250 uchar uppercorner = style.symbolTable().character( chars[0] );
00251 uchar lowercorner = style.symbolTable().character( chars[1] );
00252
00253
00254
QFont f = style.symbolTable().font( chars[0] );
00255 f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
00256
QFontMetrics fm( f );
00257
LuPtRect upperBound = fm.boundingRect( uppercorner );
00258
LuPtRect lowerBound = fm.boundingRect( lowercorner );
00259
00260
00261 setWidth( style.ptToLayoutUnitPt( fm.width(
QChar( uppercorner ) ) ) );
00262 luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() );
00263
00264
00265
00266 setHeight( QMAX( edgeHeight, height ) );
00267 }
00268
00269
void Artwork::drawBigRoundBracket(
QPainter& p,
const ContextStyle& style,
const QChar chars[],
00270 luPixel x, luPixel y, luPt charHeight )
00271 {
00272 uchar uppercorner = style.symbolTable().character( chars[0] );
00273 uchar lowercorner = style.symbolTable().character( chars[1] );
00274 uchar line = style.symbolTable().character( chars[2] );
00275
00276
QFont f = style.symbolTable().font( chars[0] );
00277 f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight,
false ) );
00278 p.setFont(f);
00279
00280
QFontMetrics fm(f);
00281
QRect upperBound = fm.boundingRect(uppercorner);
00282
QRect lowerBound = fm.boundingRect(lowercorner);
00283
QRect lineBound = fm.boundingRect(line);
00284
00285 pixel ptX = style.layoutUnitToPixelX( x );
00286 pixel ptY = style.layoutUnitToPixelY( y );
00287 pixel height = style.layoutUnitToPixelY( getHeight() );
00288
00289
00290
00291
00292
00293
00294
00295 p.drawText( ptX, ptY-upperBound.top(),
QString(
QChar( uppercorner ) ) );
00296 p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
00297
QString(
QChar( lowercorner ) ) );
00298
00299
00300
00301 pixel safety = 0;
00302
00303 pixel gap = height - upperBound.height() - lowerBound.height();
00304 pixel lineHeight = lineBound.height() - safety;
00305
int lineCount = qRound( static_cast<double>( gap ) / lineHeight );
00306 pixel start = upperBound.height()-lineBound.top() - safety;
00307
00308
for (
int i = 0; i < lineCount; i++) {
00309 p.drawText( ptX, ptY+start+i*lineHeight,
QString(
QChar(line)));
00310 }
00311 pixel remaining = gap - lineCount*lineHeight;
00312 pixel dist = ( lineHeight - remaining ) / 2;
00313 p.drawText( ptX, ptY+height-upperBound.height()+dist-lineBound.height()-lineBound.top(),
00314
QString(
QChar( line ) ) );
00315 }
00316
00317
void Artwork::calcCurlyBracket(
const ContextStyle& style,
const QChar chars[],
00318 luPt height, luPt charHeight )
00319 {
00320 uchar uppercorner = style.symbolTable().character( chars[0] );
00321 uchar lowercorner = style.symbolTable().character( chars[1] );
00322
00323 uchar middle = style.symbolTable().character( chars[3] );
00324
00325
QFont f = style.symbolTable().font( chars[0] );
00326 f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
00327
QFontMetrics fm( f );
00328
LuPtRect upperBound = fm.boundingRect( uppercorner );
00329
LuPtRect lowerBound = fm.boundingRect( lowercorner );
00330
00331
LuPtRect middleBound = fm.boundingRect( middle );
00332
00333 setWidth( style.ptToLayoutUnitPt( fm.width(
QChar( uppercorner ) ) ) );
00334 luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+
00335 lowerBound.height()+
00336 middleBound.height() );
00337
00338
00339
00340 setHeight( QMAX( edgeHeight, height ) );
00341 }
00342
00343
void Artwork::drawBigCurlyBracket(
QPainter& p,
const ContextStyle& style,
const QChar chars[],
00344 luPixel x, luPixel y, luPt charHeight )
00345 {
00346
00347
QFont f = style.symbolTable().font( chars[0] );
00348 f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight,
false ) );
00349 p.setFont(f);
00350
00351 uchar uppercorner = style.symbolTable().character( chars[0] );
00352 uchar lowercorner = style.symbolTable().character( chars[1] );
00353 uchar line = style.symbolTable().character( chars[2] );
00354 uchar middle = style.symbolTable().character( chars[3] );
00355
00356
QFontMetrics fm(p.fontMetrics());
00357
QRect upperBound = fm.boundingRect(uppercorner);
00358
QRect lowerBound = fm.boundingRect(lowercorner);
00359
QRect middleBound = fm.boundingRect(middle);
00360
QRect lineBound = fm.boundingRect(line);
00361
00362 pixel ptX = style.layoutUnitToPixelX( x );
00363 pixel ptY = style.layoutUnitToPixelY( y );
00364 pixel height = style.layoutUnitToPixelY( getHeight() );
00365
00366
00367
00368
00369 p.drawText( ptX, ptY-upperBound.top(),
QString(
QChar( uppercorner ) ) );
00370 p.drawText( ptX, ptY+(height-middleBound.height())/2-middleBound.top(),
00371
QString(
QChar( middle ) ) );
00372 p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
00373
QString(
QChar( lowercorner ) ) );
00374
00375
00376
00377
00378
00379 pixel safety = 0;
00380
00381 pixel lineHeight = lineBound.height() - safety;
00382 pixel gap = height/2 - upperBound.height() - middleBound.height() / 2;
00383
00384
if (gap > 0) {
00385
QString ch =
QString(
QChar(line));
00386
int lineCount = qRound( gap / lineHeight ) + 1;
00387
00388 pixel start = (height - middleBound.height()) / 2 + safety;
00389
for (
int i = 0; i < lineCount; i++) {
00390 p.drawText( ptX, ptY-lineBound.top()+QMAX( start-(i+1)*lineHeight,
00391 upperBound.width() ),
00392 ch );
00393 }
00394
00395 start = (height + middleBound.height()) / 2 - safety;
00396
for (
int i = 0; i < lineCount; i++) {
00397 p.drawText( ptX, ptY-lineBound.top()+QMIN( start+i*lineHeight,
00398 height-upperBound.width()-lineBound.height() ),
00399 ch );
00400 }
00401 }
00402 }
00403
00404 KFORMULA_NAMESPACE_END