lib Library API Documentation

fontstyle.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Ulrich Kuettler <ulrich.kuettler@gmx.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
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 // We claim that all chars come from the same font.
00039 // It's up to the font tables to ensure this.
00040 const QChar leftRoundBracket[] = {
00041     0xF8EB, // uppercorner
00042     0xF8ED, // lowercorner
00043     0xF8EC  // line
00044 };
00045 const QChar leftSquareBracket[] = {
00046     0xF8EE, // uppercorner
00047     0xF8F0, // lowercorner
00048     0xF8EF  // line
00049 };
00050 const QChar leftCurlyBracket[] = {
00051     0xF8F1, // uppercorner
00052     0xF8F3, // lowercorner
00053     0xF8F4, // line
00054     0xF8F2  // middle
00055 };
00056 
00057 const QChar leftLineBracket[] = {
00058     0xF8EF, // line
00059     0xF8EF, // line
00060     0xF8EF  // line
00061 };
00062 const QChar rightLineBracket[] = {
00063     0xF8FA, // line
00064     0xF8FA, // line
00065     0xF8FA  // line
00066 };
00067 
00068 const QChar rightRoundBracket[] = {
00069     0xF8F6, // uppercorner
00070     0xF8F8, // lowercorner
00071     0xF8F7  // line
00072 };
00073 const QChar rightSquareBracket[] = {
00074     0xF8F9, // uppercorner
00075     0xF8FB, // lowercorner
00076     0xF8FA  // line
00077 };
00078 const QChar rightCurlyBracket[] = {
00079     0xF8FC, // uppercorner
00080     0xF8FE, // lowercorner
00081     0xF8F4, // line
00082     0xF8FD  // middle
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         //calcCharSize(style, mySize, spaceChar);
00127         setHeight(0);
00128         //setWidth(style.getEmptyRectWidth());
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     //QFont f = style.getSymbolFont();
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     //f.setPointSize( height );
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     //uchar line = style.symbolTable().character( chars[2] );
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     //LuPtRect lineBound = fm.boundingRect( line );
00260 
00261     setWidth( style.ptToLayoutUnitPt( fm.width( QChar( uppercorner ) ) ) );
00262     luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() );
00263     //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() );
00264 
00265     //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight );
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 //     p.setPen( Qt::red );
00290 //     //p.drawRect( ptX, ptY, upperBound.width(), upperBound.height() + lowerBound.height() );
00291 //     p.drawRect( ptX, ptY, style.layoutUnitToPixelX( getWidth() ),
00292 //                 style.layoutUnitToPixelY( getHeight() ) );
00293 
00294 //     p.setPen( Qt::black );
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     // for printing
00300     //pt safety = lineBound.height() / 10.0;
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     //uchar line = style.symbolTable().character( chars[2] );
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     //LuPtRect lineBound = fm.boundingRect( line );
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     //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() );
00338 
00339     //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight );
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     //QFont f = style.getSymbolFont();
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     //p.setPen(Qt::gray);
00367     //p.drawRect(x, y, upperBound.width() + offset, height);
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     // for printing
00376     // If the world was perfect and the urw-symbol font correct
00377     // this could be 0.
00378     //lu safety = lineBound.height() / 10;
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
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 13:19:21 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2003