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