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& r,
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 if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
00176 return;
00177
00178 painter.setPen(style.getDefaultColor());
00179
00180 switch (type) {
00181 case LeftSquareBracket:
00182 drawCharacter(painter, style, myX, myY, mySize, leftSquareBracketChar);
00183 break;
00184 case RightSquareBracket:
00185 drawCharacter(painter, style, myX, myY, mySize, rightSquareBracketChar);
00186 break;
00187 case LeftCurlyBracket:
00188 drawCharacter(painter, style, myX, myY, mySize, leftCurlyBracketChar);
00189 break;
00190 case RightCurlyBracket:
00191 drawCharacter(painter, style, myX, myY, mySize, rightCurlyBracketChar);
00192 break;
00193 case LeftLineBracket:
00194 case RightLineBracket:
00195 drawCharacter(painter, style, myX, myY, mySize, verticalLineChar);
00196 break;
00197 case SlashBracket:
00198 drawCharacter(painter, style, myX, myY, mySize, slashChar);
00199 break;
00200 case BackSlashBracket:
00201 drawCharacter(painter, style, myX, myY, mySize, backSlashChar);
00202 break;
00203 case LeftCornerBracket:
00204 drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar);
00205 break;
00206 case RightCornerBracket:
00207 drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar);
00208 break;
00209 case LeftRoundBracket:
00210 drawCharacter(painter, style, myX, myY, mySize, leftParenthesisChar);
00211 break;
00212 case RightRoundBracket:
00213 drawCharacter(painter, style, myX, myY, mySize, rightParenthesisChar);
00214 break;
00215 case EmptyBracket:
00216 break;
00217 case Integral:
00218 case Sum:
00219 case Product:
00220 break;
00221 }
00222 }
00223
00224
00225 void Artwork::calcCharSize( const ContextStyle& style, luPt height, QChar ch )
00226 {
00227
00228 uchar c = style.symbolTable().character( ch );
00229 QFont f = style.symbolTable().font( ch );
00230 calcCharSize( style, f, height, c );
00231 }
00232
00233
00234 void Artwork::drawCharacter( QPainter& painter, const ContextStyle& style,
00235 luPixel x, luPixel y,
00236 luPt height, QChar ch )
00237 {
00238 uchar c = style.symbolTable().character( ch );
00239 QFont f = style.symbolTable().font( ch );
00240 drawCharacter( painter, style, f, x, y, height, c );
00241 }
00242
00243
00244 void Artwork::calcCharSize( const ContextStyle& style, QFont f,
00245 luPt height, uchar c )
00246 {
00247 f.setPointSizeFloat( style.layoutUnitPtToPt( height ) );
00248
00249 QFontMetrics fm(f);
00250 setWidth( style.ptToLayoutUnitPt( fm.width( c ) ) );
00251 LuPixelRect bound = fm.boundingRect( c );
00252 setHeight( style.ptToLayoutUnitPt( bound.height() ) );
00253 setBaseline( style.ptToLayoutUnitPt( -bound.top() ) );
00254 }
00255
00256
00257 void Artwork::drawCharacter( QPainter& painter, const ContextStyle& style,
00258 QFont f,
00259 luPixel x, luPixel y, luPt height, uchar c )
00260 {
00261 f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) );
00262
00263 painter.setFont( f );
00264 painter.drawText( style.layoutUnitToPixelX( x ),
00265 style.layoutUnitToPixelY( y+getBaseline() ),
00266 QString( QChar( c ) ) );
00267 }
00268
00269
00270 void Artwork::calcRoundBracket( const ContextStyle& style, const QChar chars[],
00271 luPt height, luPt charHeight )
00272 {
00273 uchar uppercorner = style.symbolTable().character( chars[0] );
00274 uchar lowercorner = style.symbolTable().character( chars[1] );
00275
00276
00277 QFont f = style.symbolTable().font( chars[0] );
00278 f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
00279 QFontMetrics fm( f );
00280 LuPtRect upperBound = fm.boundingRect( uppercorner );
00281 LuPtRect lowerBound = fm.boundingRect( lowercorner );
00282
00283
00284 setWidth( style.ptToLayoutUnitPt( fm.width( QChar( uppercorner ) ) ) );
00285 luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() );
00286
00287
00288
00289 setHeight( QMAX( edgeHeight, height ) );
00290 }
00291
00292 void Artwork::drawBigRoundBracket( QPainter& p, const ContextStyle& style, const QChar chars[],
00293 luPixel x, luPixel y, luPt charHeight )
00294 {
00295 uchar uppercorner = style.symbolTable().character( chars[0] );
00296 uchar lowercorner = style.symbolTable().character( chars[1] );
00297 uchar line = style.symbolTable().character( chars[2] );
00298
00299 QFont f = style.symbolTable().font( chars[0] );
00300 f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) );
00301 p.setFont(f);
00302
00303 QFontMetrics fm(f);
00304 QRect upperBound = fm.boundingRect(uppercorner);
00305 QRect lowerBound = fm.boundingRect(lowercorner);
00306 QRect lineBound = fm.boundingRect(line);
00307
00308 pixel ptX = style.layoutUnitToPixelX( x );
00309 pixel ptY = style.layoutUnitToPixelY( y );
00310 pixel height = style.layoutUnitToPixelY( getHeight() );
00311
00312
00313
00314
00315
00316
00317
00318 p.drawText( ptX, ptY-upperBound.top(), QString( QChar( uppercorner ) ) );
00319 p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
00320 QString( QChar( lowercorner ) ) );
00321
00322
00323
00324 pixel safety = 0;
00325
00326 pixel gap = height - upperBound.height() - lowerBound.height();
00327 pixel lineHeight = lineBound.height() - safety;
00328 int lineCount = qRound( static_cast<double>( gap ) / lineHeight );
00329 pixel start = upperBound.height()-lineBound.top() - safety;
00330
00331 for (int i = 0; i < lineCount; i++) {
00332 p.drawText( ptX, ptY+start+i*lineHeight, QString(QChar(line)));
00333 }
00334 pixel remaining = gap - lineCount*lineHeight;
00335 pixel dist = ( lineHeight - remaining ) / 2;
00336 p.drawText( ptX, ptY+height-upperBound.height()+dist-lineBound.height()-lineBound.top(),
00337 QString( QChar( line ) ) );
00338 }
00339
00340 void Artwork::calcCurlyBracket( const ContextStyle& style, const QChar chars[],
00341 luPt height, luPt charHeight )
00342 {
00343 uchar uppercorner = style.symbolTable().character( chars[0] );
00344 uchar lowercorner = style.symbolTable().character( chars[1] );
00345
00346 uchar middle = style.symbolTable().character( chars[3] );
00347
00348 QFont f = style.symbolTable().font( chars[0] );
00349 f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
00350 QFontMetrics fm( f );
00351 LuPtRect upperBound = fm.boundingRect( uppercorner );
00352 LuPtRect lowerBound = fm.boundingRect( lowercorner );
00353
00354 LuPtRect middleBound = fm.boundingRect( middle );
00355
00356 setWidth( style.ptToLayoutUnitPt( fm.width( QChar( uppercorner ) ) ) );
00357 luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+
00358 lowerBound.height()+
00359 middleBound.height() );
00360
00361
00362
00363 setHeight( QMAX( edgeHeight, height ) );
00364 }
00365
00366 void Artwork::drawBigCurlyBracket( QPainter& p, const ContextStyle& style, const QChar chars[],
00367 luPixel x, luPixel y, luPt charHeight )
00368 {
00369
00370 QFont f = style.symbolTable().font( chars[0] );
00371 f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) );
00372 p.setFont(f);
00373
00374 uchar uppercorner = style.symbolTable().character( chars[0] );
00375 uchar lowercorner = style.symbolTable().character( chars[1] );
00376 uchar line = style.symbolTable().character( chars[2] );
00377 uchar middle = style.symbolTable().character( chars[3] );
00378
00379 QFontMetrics fm(p.fontMetrics());
00380 QRect upperBound = fm.boundingRect(uppercorner);
00381 QRect lowerBound = fm.boundingRect(lowercorner);
00382 QRect middleBound = fm.boundingRect(middle);
00383 QRect lineBound = fm.boundingRect(line);
00384
00385 pixel ptX = style.layoutUnitToPixelX( x );
00386 pixel ptY = style.layoutUnitToPixelY( y );
00387 pixel height = style.layoutUnitToPixelY( getHeight() );
00388
00389
00390
00391
00392 p.drawText( ptX, ptY-upperBound.top(), QString( QChar( uppercorner ) ) );
00393 p.drawText( ptX, ptY+(height-middleBound.height())/2-middleBound.top(),
00394 QString( QChar( middle ) ) );
00395 p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
00396 QString( QChar( lowercorner ) ) );
00397
00398
00399
00400
00401
00402 pixel safety = 0;
00403
00404 pixel lineHeight = lineBound.height() - safety;
00405 pixel gap = height/2 - upperBound.height() - middleBound.height() / 2;
00406
00407 if (gap > 0) {
00408 QString ch = QString(QChar(line));
00409 int lineCount = qRound( gap / lineHeight ) + 1;
00410
00411 pixel start = (height - middleBound.height()) / 2 + safety;
00412 for (int i = 0; i < lineCount; i++) {
00413 p.drawText( ptX, ptY-lineBound.top()+QMAX( start-(i+1)*lineHeight,
00414 upperBound.width() ),
00415 ch );
00416 }
00417
00418 start = (height + middleBound.height()) / 2 - safety;
00419 for (int i = 0; i < lineCount; i++) {
00420 p.drawText( ptX, ptY-lineBound.top()+QMIN( start+i*lineHeight,
00421 height-upperBound.width()-lineBound.height() ),
00422 ch );
00423 }
00424 }
00425 }
00426
00427 KFORMULA_NAMESPACE_END