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