00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef QFONTDATA_P_H
00039 #define QFONTDATA_P_H
00040
00041 #ifndef QT_H
00042 #include <qcache.h>
00043 #include <qobject.h>
00044 #include <qpaintdevice.h>
00045 #endif // QT_H
00046 #include <limits.h>
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class QPaintDevice;
00061
00062 #ifdef Q_WS_WIN
00063 #include <qt_windows.h>
00064 #endif
00065
00066 #ifdef Q_WS_X11
00067 #include <qt_x11.h>
00068
00069 class QCharStruct;
00070 #endif
00071
00072
00073 struct QFontDef {
00074 QFontDef()
00075 : pixelSize(0), pointSize(0), lbearing(SHRT_MIN), rbearing(SHRT_MIN),
00076 styleStrategy(QFont::PreferDefault), styleHint(QFont::AnyStyle),
00077 weight(0), italic(FALSE), underline(FALSE), strikeOut(FALSE),
00078 fixedPitch(FALSE), hintSetByUser(FALSE), rawMode(FALSE), dirty(TRUE)
00079 { ; }
00080
00081 QString family;
00082 QString addStyle;
00083
00084 int pixelSize;
00085 int pointSize;
00086 short lbearing;
00087 short rbearing;
00088
00089 ushort styleStrategy;
00090 uchar styleHint;
00091 uchar weight;
00092
00093 bool italic;
00094 bool underline;
00095 bool strikeOut;
00096 bool fixedPitch;
00097 bool hintSetByUser;
00098 bool rawMode;
00099
00100 bool dirty;
00101 };
00102
00103
00104 class QTextCodec;
00105
00106 #ifdef Q_WS_X11
00107
00108
00109
00110 class QFontStruct : public QShared
00111 {
00112 public:
00113 QFontStruct(Qt::HANDLE h, Qt::HANDLE xfth, Qt::HANDLE xftp,
00114 QCString n, QTextCodec *c, int a) :
00115 QShared(), handle(h), xfthandle(xfth), xftpattern(xftp),
00116 name(n), codec(c), cache_cost(a), scale( 1. )
00117 { ; }
00118
00119 ~QFontStruct();
00120
00121 Qt::HANDLE handle, xfthandle, xftpattern;
00122 QCString name;
00123 QTextCodec *codec;
00124 int cache_cost;
00125 float scale;
00126 };
00127
00128 enum { widthCacheSize = 0x500 };
00129
00130 class QFontX11Data
00131 {
00132 public:
00133
00134 QFontStruct *fontstruct[QFont::LastPrivateScript];
00135
00136 uchar widthCache[widthCacheSize];
00137
00138 QFontX11Data();
00139 ~QFontX11Data();
00140 };
00141
00142 #endif // Q_WS_X11
00143
00144
00145 #ifdef Q_WS_WIN
00146
00147 class QFontStruct : public QShared
00148 {
00149 public:
00150 QFontStruct( const QString &key );
00151 ~QFontStruct() { reset(); }
00152 bool dirty() const { return hfont == 0; }
00153 HDC dc() const;
00154 HFONT font() const { return hfont; }
00155 const TEXTMETRICA *textMetricA() const { return &tm.a; }
00156 const TEXTMETRICW *textMetricW() const { return &tm.w; }
00157 QString key() const { return k; }
00158 void reset();
00159
00160 QString k;
00161 HDC hdc;
00162 HFONT hfont;
00163 uint stockFont:1;
00164 uint paintDevice:1;
00165 uint useTextOutA:1;
00166 union {
00167 TEXTMETRICW w;
00168 TEXTMETRICA a;
00169 } tm;
00170 int lw;
00171 int cache_cost;
00172
00173 };
00174
00175 #endif // Q_WS_WIN
00176
00177 #if defined( Q_WS_MAC )
00178
00179 #if defined( Q_WS_MACX )
00180 # define QMAC_FONT_ATSUI
00181 #endif
00182 #include "qt_mac.h"
00183 class QMacFontInfo;
00184
00185 class QFontStruct : public QShared
00186 {
00187 public:
00188 inline QFontStruct() : QShared(), info(NULL), fnum(-1), cache_cost(0), internal_fi(NULL) { }
00189 #if defined( QMAC_FONT_ATSUI ) && 0
00190 ATSFontMetrics *info;
00191 int maxWidth() const { return (int)info->maxAdvanceWidth; }
00192 #else
00193 FontInfo *info;
00194 int maxWidth() const { return info->widMax; }
00195 #endif
00196 int ascent() const { return (int)info->ascent; }
00197 int descent() const { return (int)info->descent; }
00198 int leading() const { return (int)info->leading; }
00199 int minLeftBearing() const { return 0; }
00200 int minRightBearing() const { return 0; }
00201
00202 short fnum;
00203 int psize, cache_cost;
00204 QMacFontInfo *internal_fi;
00205 };
00206
00207 #endif
00208
00209 #ifdef Q_WS_QWS
00210 class QFontStruct;
00211 class QGfx;
00212 #endif
00213
00214 typedef QCacheIterator<QFontStruct> QFontCacheIterator;
00215 class QFontCache : public QObject, public QCache<QFontStruct>
00216 {
00217 public:
00218 QFontCache();
00219 ~QFontCache();
00220
00221 bool insert(const QString &, const QFontStruct *, int c);
00222 #ifndef Q_WS_MAC
00223 void deleteItem(Item d);
00224 #endif
00225 void timerEvent(QTimerEvent *);
00226
00227
00228 protected:
00229
00230
00231 private:
00232 int timer_id;
00233 bool fast;
00234 };
00235
00236
00237
00238 class QFontPrivate : public QShared
00239 {
00240 public:
00241 static QFontCache *fontCache;
00242
00243
00244 public:
00245
00246 QFontPrivate();
00247 QFontPrivate(const QFontPrivate &fp);
00248 QFontPrivate( const QFontPrivate &fp, QPaintDevice *pd );
00249 ~QFontPrivate();
00250
00251
00252 QFontDef request;
00253
00254 QFontDef actual;
00255
00256 bool exactMatch;
00257 int lineWidth;
00258
00259
00260 QString defaultFamily() const;
00261 QString lastResortFamily() const;
00262 QString lastResortFont() const;
00263 QString key() const;
00264
00265 static int getFontWeight(const QCString &, bool = FALSE);
00266 QRect boundingRect( const QChar &ch );
00267
00268 struct TextRun {
00269 TextRun()
00270 {
00271 xoff = 0;
00272 yoff = 0;
00273 x2off = 0;
00274 script = QFont::NoScript;
00275 string = 0;
00276 length = 0;
00277 next = 0;
00278 }
00279
00280 ~TextRun()
00281 {
00282 if ( next )
00283 delete next;
00284 }
00285
00286 void setParams( int x, int y, int x2, const QChar *s, int len,
00287 QFont::Script sc = QFont::NoScript ) {
00288 xoff = x;
00289 yoff = y;
00290 x2off = x2;
00291 string = s;
00292 length = len;
00293 script = sc;
00294 }
00295 int xoff;
00296 int yoff;
00297 int x2off;
00298 QFont::Script script;
00299 const QChar *string;
00300 int length;
00301 TextRun *next;
00302 #ifdef Q_WS_X11
00303 QByteArray mapped;
00304 #endif
00305 };
00306
00307
00308
00309
00310 int textWidth( const QString &str, int pos, int len );
00311
00312
00313
00314 QFont::Script scriptForChar(const QChar &c);
00315
00316 #ifdef Q_WS_X11
00317 QFont::Script hanHack( const QChar & c );
00318 static char **getXFontNames(const char *, int *);
00319 static bool fontExists(const QString &);
00320 static bool parseXFontName(char *, char **);
00321 static QCString fixXLFD( const QCString & );
00322 static bool fillFontDef(XFontStruct *, QFontDef *, int);
00323 static bool fillFontDef(const QCString &, QFontDef *, int);
00324
00325 static inline bool isZero(char *x)
00326 {
00327 return (x[0] == '0' && x[1] == 0);
00328 }
00329
00330 static inline bool isScalable( char **tokens )
00331 {
00332 return (isZero(tokens[PixelSize]) &&
00333 isZero(tokens[PointSize]) &&
00334 isZero(tokens[AverageWidth]));
00335 }
00336
00337 static inline bool isSmoothlyScalable( char **tokens )
00338 {
00339 return (isZero(tokens[ResolutionX]) && isZero(tokens[ResolutionY]));
00340 }
00341
00342 static inline bool isFixedPitch( char **tokens )
00343 {
00344 return (tokens[Spacing][0] == 'm' ||
00345 tokens[Spacing][0] == 'c' ||
00346 tokens[Spacing][0] == 'M' ||
00347 tokens[Spacing][0] == 'C');
00348 }
00349
00350
00351 enum FontFieldNames {
00352 Foundry,
00353 Family,
00354 Weight,
00355 Slant,
00356 Width,
00357 AddStyle,
00358 PixelSize,
00359 PointSize,
00360 ResolutionX,
00361 ResolutionY,
00362 Spacing,
00363 AverageWidth,
00364 CharsetRegistry,
00365 CharsetEncoding,
00366 NFontFields
00367 };
00368
00369 #ifndef QT_NO_XFTFREETYPE
00370 XftPattern *findXftFont(const QChar &, bool *, double *scale) const;
00371 XftPattern *bestXftPattern(const QString &, const QString &, const QChar &, double *scale) const;
00372 #endif // QT_NO_XFTFREETYPE
00373 QCString findFont(QFont::Script, bool *, double *) const;
00374 QCString bestFamilyMember(QFont::Script, const QString &, const QString &,
00375 const QString &, int *, double *) const;
00376 QCString bestMatch(const char *, int *, QFont::Script, double *) const;
00377 int fontMatchScore(const char *, QCString &, float *, int *, bool *,
00378 bool *, QFont::Script, double *) const;
00379 void initFontInfo(QFont::Script, double scale);
00380 void load(QFont::Script = QFont::NoScript, bool = TRUE);
00381 bool loadUnicode(QFont::Script, const QChar &);
00382 void computeLineWidth();
00383
00384 int textWidth( const QString &str, int pos, int len, TextRun *cache );
00385 void textExtents( const QString &str, int pos, int len, QCharStruct *overall );
00386 void drawText( Display *dpy, int screen, Qt::HANDLE hd, Qt::HANDLE rendhd,
00387 GC gc, const QColor &pen, Qt::BGMode, const QColor &bgcolor,
00388 int x, int y, const TextRun *cache, int pdWidth );
00389 bool inFont( const QChar &ch );
00390
00391 QFontX11Data x11data;
00392 static QFont::Script defaultScript;
00393 int x11Screen;
00394 #endif // Q_WS_X11
00395
00396 QPaintDevice *paintdevice;
00397
00398 #ifdef Q_WS_WIN
00399 void load();
00400 void initFontInfo();
00401 HFONT create( bool *stockFont, HDC hdc = 0, bool compatMode = FALSE );
00402 QFontStruct *fin;
00403
00404 void buildCache( HDC hdc, const QString &str, int pos, int len, TextRun *cache );
00405 void drawText( HDC hdc, int x, int y, TextRun *cache );
00406 #endif // Q_WS_WIN
00407
00408 #ifdef Q_WS_QWS
00409 void load();
00410 QFontStruct *fin;
00411 int textWidth( const QString &str, int pos, int len, TextRun *cache );
00412 void drawText( QGfx *gfx, int x, int y, const TextRun *cache );
00413 #endif
00414
00415 #if defined( Q_WS_MAC )
00416 void macSetFont(QPaintDevice *);
00417 void drawText(int x, int y, const QString &s, int from, int len, QPaintDevice *dev, const QRegion *rgn, int dir);
00418 void computeLineWidth();
00419 void load();
00420 QFontStruct *fin;
00421 #endif
00422
00423 };
00424
00425 inline QFontPrivate::QFontPrivate()
00426 : QShared(), exactMatch(FALSE), lineWidth(1)
00427 {
00428
00429 #if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
00430 fin = 0;
00431 #endif // Q_WS_WIN || Q_WS_QWS
00432 #if defined(Q_WS_X11)
00433 x11Screen = QPaintDevice::x11AppScreen();
00434 #endif // Q_WS_X11
00435 paintdevice = 0;
00436 }
00437
00438 inline QFontPrivate::QFontPrivate(const QFontPrivate &fp)
00439 : QShared(), request(fp.request), actual(fp.actual),
00440 exactMatch(fp.exactMatch), lineWidth(1)
00441 {
00442 Q_ASSERT(!fp.paintdevice);
00443 #if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
00444 fin = 0;
00445 #endif // Q_WS_WIN || Q_WS_QWS
00446 #if defined(Q_WS_X11)
00447 x11Screen = fp.x11Screen;
00448 #endif // Q_WS_X11
00449 paintdevice = 0;
00450 }
00451
00452 inline QFontPrivate::QFontPrivate( const QFontPrivate &fp, QPaintDevice *pd )
00453 : QShared(), request(fp.request), actual(fp.actual),
00454 exactMatch(fp.exactMatch), lineWidth(1)
00455 {
00456
00457 #if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
00458 fin = 0;
00459 #endif // Q_WS_WIN || Q_WS_QWS
00460 #if defined(Q_WS_X11)
00461 x11Screen = pd->x11Screen();
00462 #endif // Q_WS_X11
00463 paintdevice = pd;
00464 }
00465
00466 #ifndef Q_WS_QWS
00467 inline QFontPrivate::~QFontPrivate()
00468 {
00469 #if defined(Q_WS_WIN)
00470 if( fin )
00471 fin->deref();
00472 #endif
00473 #if defined(Q_WS_MAC)
00474 if( fin && fin->deref() )
00475 delete fin;
00476 #endif
00477 }
00478 #endif
00479
00480 #endif // QFONTDATA_P_H