src/gui/text/qfont_x11.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #define QT_FATAL_ASSERT
       
    43 
       
    44 #include "qplatformdefs.h"
       
    45 
       
    46 #include "qfont.h"
       
    47 #include "qapplication.h"
       
    48 #include "qfontinfo.h"
       
    49 #include "qfontdatabase.h"
       
    50 #include "qfontmetrics.h"
       
    51 #include "qpaintdevice.h"
       
    52 #include "qtextcodec.h"
       
    53 #include "qiodevice.h"
       
    54 #include "qhash.h"
       
    55 
       
    56 #include <private/qunicodetables_p.h>
       
    57 #include "qfont_p.h"
       
    58 #include "qfontengine_p.h"
       
    59 #include "qfontengine_x11_p.h"
       
    60 #include "qtextengine_p.h"
       
    61 
       
    62 #include <private/qt_x11_p.h>
       
    63 #include "qx11info_x11.h"
       
    64 
       
    65 #include <time.h>
       
    66 #include <stdlib.h>
       
    67 #include <ctype.h>
       
    68 
       
    69 #define QFONTLOADER_DEBUG
       
    70 #define QFONTLOADER_DEBUG_VERBOSE
       
    71 
       
    72 QT_BEGIN_NAMESPACE
       
    73 
       
    74 double qt_pixelSize(double pointSize, int dpi)
       
    75 {
       
    76     if (pointSize < 0)
       
    77         return -1.;
       
    78     if (dpi == 75) // the stupid 75 dpi setting on X11
       
    79         dpi = 72;
       
    80     return (pointSize * dpi) /72.;
       
    81 }
       
    82 
       
    83 double qt_pointSize(double pixelSize, int dpi)
       
    84 {
       
    85     if (pixelSize < 0)
       
    86         return -1.;
       
    87     if (dpi == 75) // the stupid 75 dpi setting on X11
       
    88         dpi = 72;
       
    89     return pixelSize * 72. / ((double) dpi);
       
    90 }
       
    91 
       
    92 /*
       
    93   Removes wildcards from an XLFD.
       
    94 
       
    95   Returns \a xlfd with all wildcards removed if a match for \a xlfd is
       
    96   found, otherwise it returns \a xlfd.
       
    97 */
       
    98 static QByteArray qt_fixXLFD(const QByteArray &xlfd)
       
    99 {
       
   100     QByteArray ret = xlfd;
       
   101     int count = 0;
       
   102     char **fontNames =
       
   103         XListFonts(QX11Info::display(), xlfd, 32768, &count);
       
   104     if (count > 0)
       
   105         ret = fontNames[0];
       
   106     XFreeFontNames(fontNames);
       
   107     return ret ;
       
   108 }
       
   109 
       
   110 typedef QHash<int, QString> FallBackHash;
       
   111 Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
       
   112 
       
   113 // Returns the user-configured fallback family for the specified script.
       
   114 QString qt_fallback_font_family(int script)
       
   115 {
       
   116     FallBackHash *hash = fallBackHash();
       
   117     return hash->value(script);
       
   118 }
       
   119 
       
   120 // Sets the fallback family for the specified script.
       
   121 Q_GUI_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
       
   122 {
       
   123     FallBackHash *hash = fallBackHash();
       
   124     if (!family.isEmpty())
       
   125         hash->insert(script, family);
       
   126     else
       
   127         hash->remove(script);
       
   128 }
       
   129 
       
   130 int QFontPrivate::defaultEncodingID = -1;
       
   131 
       
   132 void QFont::initialize()
       
   133 {
       
   134     extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
       
   135     QTextCodec *codec = QTextCodec::codecForLocale();
       
   136     // determine the default encoding id using the locale, otherwise
       
   137     // fallback to latin1 (mib == 4)
       
   138     int mib = codec ? codec->mibEnum() : 4;
       
   139 
       
   140     // for asian locales, use the mib for the font codec instead of the locale codec
       
   141     switch (mib) {
       
   142     case 38: // eucKR
       
   143         mib = 36;
       
   144         break;
       
   145 
       
   146     case 2025: // GB2312
       
   147         mib = 57;
       
   148         break;
       
   149 
       
   150     case 113: // GBK
       
   151         mib = -113;
       
   152         break;
       
   153 
       
   154     case 114: // GB18030
       
   155         mib = -114;
       
   156         break;
       
   157 
       
   158     case 2026: // Big5
       
   159         mib = -2026;
       
   160         break;
       
   161 
       
   162     case 2101: // Big5-HKSCS
       
   163         mib = -2101;
       
   164         break;
       
   165 
       
   166     case 16: // JIS7
       
   167         mib = 15;
       
   168         break;
       
   169 
       
   170     case 17: // SJIS
       
   171     case 18: // eucJP
       
   172         mib = 63;
       
   173         break;
       
   174     }
       
   175 
       
   176     // get the default encoding id for the locale encoding...
       
   177     QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
       
   178 }
       
   179 
       
   180 void QFont::cleanup()
       
   181 {
       
   182     QFontCache::cleanup();
       
   183 }
       
   184 
       
   185 /*!
       
   186   \internal
       
   187   X11 Only: Returns the screen with which this font is associated.
       
   188 */
       
   189 int QFont::x11Screen() const
       
   190 {
       
   191     return d->screen;
       
   192 }
       
   193 
       
   194 /*! \internal
       
   195     X11 Only: Associate the font with the specified \a screen.
       
   196 */
       
   197 void QFont::x11SetScreen(int screen)
       
   198 {
       
   199     if (screen < 0) // assume default
       
   200         screen = QX11Info::appScreen();
       
   201 
       
   202     if (screen == d->screen)
       
   203         return; // nothing to do
       
   204 
       
   205     detach();
       
   206     d->screen = screen;
       
   207 }
       
   208 
       
   209 Qt::HANDLE QFont::handle() const
       
   210 {
       
   211     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
       
   212     Q_ASSERT(engine != 0);
       
   213     if (engine->type() == QFontEngine::Multi)
       
   214         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
       
   215     if (engine->type() == QFontEngine::XLFD)
       
   216         return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
       
   217     return 0;
       
   218 }
       
   219 
       
   220 
       
   221 FT_Face QFont::freetypeFace() const
       
   222 {
       
   223 #ifndef QT_NO_FREETYPE
       
   224     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
       
   225     if (engine->type() == QFontEngine::Multi)
       
   226         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
       
   227 #ifndef QT_NO_FONTCONFIG
       
   228     if (engine->type() == QFontEngine::Freetype) {
       
   229         const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
       
   230         return ft->non_locked_face();
       
   231     } else
       
   232 #endif
       
   233     if (engine->type() == QFontEngine::XLFD) {
       
   234         const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
       
   235         return xlfd->non_locked_face();
       
   236     }
       
   237 #endif
       
   238     return 0;
       
   239 }
       
   240 
       
   241 QString QFont::rawName() const
       
   242 {
       
   243     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
       
   244     Q_ASSERT(engine != 0);
       
   245     if (engine->type() == QFontEngine::Multi)
       
   246         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
       
   247     if (engine->type() == QFontEngine::XLFD)
       
   248         return QString::fromLatin1(engine->name());
       
   249     return QString();
       
   250 }
       
   251 struct QtFontDesc;
       
   252 
       
   253 void QFont::setRawName(const QString &name)
       
   254 {
       
   255     detach();
       
   256 
       
   257     // from qfontdatabase_x11.cpp
       
   258     extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
       
   259 
       
   260     if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
       
   261         qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
       
   262 
       
   263         setFamily(name);
       
   264         setRawMode(true);
       
   265     } else {
       
   266         resolve_mask = QFont::AllPropertiesResolved;
       
   267     }
       
   268 }
       
   269 
       
   270 QString QFont::lastResortFamily() const
       
   271 {
       
   272     return QString::fromLatin1("Helvetica");
       
   273 }
       
   274 
       
   275 QString QFont::defaultFamily() const
       
   276 {
       
   277     switch (d->request.styleHint) {
       
   278     case QFont::Times:
       
   279         return QString::fromLatin1("Times");
       
   280 
       
   281     case QFont::Courier:
       
   282         return QString::fromLatin1("Courier");
       
   283 
       
   284     case QFont::Decorative:
       
   285         return QString::fromLatin1("Old English");
       
   286 
       
   287     case QFont::Helvetica:
       
   288     case QFont::System:
       
   289     default:
       
   290         return QString::fromLatin1("Helvetica");
       
   291     }
       
   292 }
       
   293 
       
   294 /*
       
   295   Returns a last resort raw font name for the font matching algorithm.
       
   296   This is used if even the last resort family is not available. It
       
   297   returns \e something, almost no matter what.  The current
       
   298   implementation tries a wide variety of common fonts, returning the
       
   299   first one it finds. The implementation may change at any time.
       
   300 */
       
   301 static const char * const tryFonts[] = {
       
   302     "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
       
   303     "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
       
   304     "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
       
   305     "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
       
   306     "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
       
   307     "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
       
   308     "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
       
   309     "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
       
   310     "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
       
   311     "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
       
   312     "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
       
   313     "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
       
   314     "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
       
   315     "6x13",
       
   316     "7x13",
       
   317     "8x13",
       
   318     "9x15",
       
   319     "fixed",
       
   320     0
       
   321 };
       
   322 
       
   323 // Returns true if the font exists, false otherwise
       
   324 static bool fontExists(const QString &fontName)
       
   325 {
       
   326     int count;
       
   327     char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
       
   328     if (fontNames) XFreeFontNames(fontNames);
       
   329 
       
   330     return count != 0;
       
   331 }
       
   332 
       
   333 QString QFont::lastResortFont() const
       
   334 {
       
   335     static QString last;
       
   336 
       
   337     // already found
       
   338     if (! last.isNull())
       
   339         return last;
       
   340 
       
   341     int i = 0;
       
   342     const char* f;
       
   343 
       
   344     while ((f = tryFonts[i])) {
       
   345         last = QString::fromLatin1(f);
       
   346 
       
   347         if (fontExists(last))
       
   348             return last;
       
   349 
       
   350         i++;
       
   351     }
       
   352 
       
   353 #if defined(CHECK_NULL)
       
   354     qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
       
   355 #endif
       
   356     return last;
       
   357 }
       
   358 
       
   359 QT_END_NAMESPACE