font.cpp Source File (khtml Library)

| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# font.cpp

    00001
    00026 #include "font.h"
    00027 #include "khtml_factory.h"
    00028 #include "khtml_settings.h"
    00029
    00030 #include <kdebug.h>
    00031 #include <kglobal.h>
    00032
    00033 #include <qpainter.h>
    00034 #include <qfontdatabase.h>
    00035 #include <qpaintdevicemetrics.h>
    00036
    00037 using namespace khtml;
    00038
    00039 void Font::drawText( QPainter *p, int x, int y, QChar *str, int slen, int pos, int len,
    00040         int toAdd, QPainter::TextDirection d, int from, int to, QColor bg ) const
    00041 {
    00042     QString qstr = QConstString(str, slen).string();
    00043     // hack for fonts that don't have a welldefined nbsp
    00044     if ( !fontDef.hasNbsp ) {
    00045         // str.setLength() always does a deep copy, so the replacement code below is safe.
    00046         qstr.setLength( slen );
    00047         QChar *uc = (QChar *)qstr.unicode();
    00048         for( int i = 0; i < slen; i++ )
    00049             if ( (uc+i)->unicode() == 0xa0 )
    00050                 *(uc+i) = ' ';
    00051     }
    00052
    00053     // ### fixme for RTL
    00054     if ( !letterSpacing && !wordSpacing && !toAdd && from==-1 ) {
    00055         // simply draw it
    00056         p->drawText( x, y, qstr, pos, len, d );
    00057     } else {
    00058         int numSpaces = 0;
    00059         if ( toAdd ) {
    00060             for( int i = 0; i < len; i++ )
    00061                 if ( str[i+pos].direction() == QChar::DirWS )
    00062                     numSpaces++;
    00063         }
    00064
    00065         if ( d == QPainter::RTL ) {
    00066             x += width( str, slen, pos, len ) + toAdd;
    00067         }
    00068         for( int i = 0; i < len; i++ ) {
    00069             int chw = fm.charWidth( qstr, pos+i );
    00070             if ( letterSpacing )
    00071                 chw += letterSpacing;
    00072             if ( (wordSpacing || toAdd) && str[i+pos].isSpace() ) {
    00073                 chw += wordSpacing;
    00074                 if ( numSpaces ) {
    00075                     int a = toAdd/numSpaces;
    00076                     chw += a;
    00077                     toAdd -= a;
    00078                     numSpaces--;
    00079                 }
    00080             }
    00081             if ( d == QPainter::RTL )
    00082                 x -= chw;
    00083             if ( to==-1 || (i>=from && i<to) )
    00084             {
    00085                 if ( bg.isValid() )
    00086                     p->fillRect( x, y-fm.ascent(), chw, fm.height(), bg );
    00087
    00088                 p->drawText( x, y, qstr, pos+i, 1, d );
    00089             }
    00090             if ( d != QPainter::RTL )
    00091                 x += chw;
    00092         }
    00093     }
    00094 }
    00095
    00096
    00097 int Font::width( QChar *chs, int, int pos, int len ) const
    00098 {
    00099     QConstString cstr(chs+pos, len);
    00100     int w;
    00101
    00102     QString qstr = cstr.string();
    00103     // hack for fonts that don't have a welldefined nbsp
    00104     if ( !fontDef.hasNbsp ) {
    00105         // str.setLength() always does a deep copy, so the replacement code below is safe.
    00106         qstr.setLength( len );
    00107         QChar *uc = (QChar *)qstr.unicode();
    00108         for( int i = 0; i < len; i++ )
    00109             if ( (uc+i)->unicode() == 0xa0 )
    00110                 *(uc+i) = ' ';
    00111     }
    00112     // ### might be a little inaccurate
    00113     w = fm.width( qstr );
    00114
    00115     if ( letterSpacing )
    00116         w += len*letterSpacing;
    00117
    00118     if ( wordSpacing )
    00119         // add amount
    00120         for( int i = 0; i < len; i++ ) {
    00121             if( chs[i+pos].isSpace() )
    00122                 w += wordSpacing;
    00123         }
    00124
    00125     return w;
    00126 }
    00127
    00128 int Font::width( QChar *chs, int slen, int pos ) const
    00129 {
    00130     int w;
    00131     if ( !fontDef.hasNbsp && (chs+pos)->unicode() == 0xa0 )
    00132         w = fm.width( QChar( ' ' ) );
    00133     else {
    00134         QConstString cstr( chs, slen );
    00135         w = fm.charWidth( cstr.string(), pos );
    00136     }
    00137     if ( letterSpacing )
    00138         w += letterSpacing;
    00139
    00140     if ( wordSpacing && (chs+pos)->isSpace() )
    00141                 w += wordSpacing;
    00142     return w;
    00143 }
    00144
    00145
    00146 void Font::update( QPaintDeviceMetrics* devMetrics ) const
    00147 {
    00148     f.setFamily( fontDef.family.isEmpty() ? KHTMLFactory::defaultHTMLSettings()->stdFontName() : fontDef.family );
    00149     f.setItalic( fontDef.italic );
    00150     f.setWeight( fontDef.weight );
    00151
    00152     QFontDatabase db;
    00153
    00154     int size = fontDef.size;
    00155     int lDpiY = kMax(devMetrics->logicalDpiY(), 96);
    00156
    00157     // ok, now some magic to get a nice unscaled font
    00158     // all other font properties should be set before this one!!!!
    00159     if( !db.isSmoothlyScalable(f.family(), db.styleString(f)) )
    00160     {
    00161         QValueList<int> pointSizes = db.smoothSizes(f.family(), db.styleString(f));
    00162         // lets see if we find a nice looking font, which is not too far away
    00163         // from the requested one.
    00164         // kdDebug(6080) << "khtml::setFontSize family = " << f.family() << " size requested=" << size << endl;
    00165
    00166         QValueList<int>::Iterator it;
    00167         float diff = 1; // ### 100% deviation
    00168         float bestSize = 0;
    00169         for( it = pointSizes.begin(); it != pointSizes.end(); ++it )
    00170         {
    00171             float newDiff = ((*it)*(lDpiY/72.) - float(size))/float(size);
    00172             //kdDebug( 6080 ) << "smooth font size: " << *it << " diff=" << newDiff << endl;
    00173             if(newDiff < 0) newDiff = -newDiff;
    00174             if(newDiff < diff)
    00175             {
    00176                 diff = newDiff;
    00177                 bestSize = *it;
    00178             }
    00179         }
    00180         //kdDebug( 6080 ) << "best smooth font size: " << bestSize << " diff=" << diff << endl;
    00181         if ( bestSize != 0 && diff < 0.2 ) // 20% deviation, otherwise we use a scaled font...
    00182             size = (int)((bestSize*lDpiY) / 72);
    00183     }
    00184
    00185     // make sure we don't bust up X11
    00186     size = KMAX(0, KMIN(255, size));
    00187
    00188 //       qDebug("setting font to %s, italic=%d, weight=%d, size=%d", fontDef.family.latin1(), fontDef.italic,
    00189 //         fontDef.weight, size );
    00190
    00191
    00192     f.setPixelSize( size );
    00193
    00194     fm = QFontMetrics( f );
    00195     fontDef.hasNbsp = fm.inFont( 0xa0 );
    00196 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:49 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001