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
00044 if ( !fontDef.hasNbsp ) {
00045
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
00054 if ( !letterSpacing && !wordSpacing && !toAdd && from==-1 ) {
00055
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
00104 if ( !fontDef.hasNbsp ) {
00105
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
00113 w = fm.width( qstr );
00114
00115 if ( letterSpacing )
00116 w += len*letterSpacing;
00117
00118 if ( wordSpacing )
00119
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
00158
00159 if( !db.isSmoothlyScalable(f.family(), db.styleString(f)) )
00160 {
00161 QValueList<int> pointSizes = db.smoothSizes(f.family(), db.styleString(f));
00162
00163
00164
00165
00166 QValueList<int>::Iterator it;
00167 float diff = 1;
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
00173 if(newDiff < 0) newDiff = -newDiff;
00174 if(newDiff < diff)
00175 {
00176 diff = newDiff;
00177 bestSize = *it;
00178 }
00179 }
00180
00181 if ( bestSize != 0 && diff < 0.2 )
00182 size = (int)((bestSize*lDpiY) / 72);
00183 }
00184
00185
00186 size = KMAX(0, KMIN(255, size));
00187
00188
00189
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.4.