Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/text/qfontengine_ft.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5454#include <private/qpdf_p.h>
    5555#include <private/qharfbuzz_p.h>
    56 
    57 #include <private/qpdf_p.h>
    5856
    5957#include "qfontengine_ft_p.h"
     
    194192 * One font file can contain more than one font (bold/italic for example)
    195193 * find the right one and return it.
     194 *
     195 * Returns the freetype face or 0 in case of an empty file or any other problems
     196 * (like not being able to open the file)
    196197 */
    197198QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id)
     
    205206
    206207    QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0);
    207     if (!freetype) {
    208         freetype = new QFreetypeFace;
     208    if (freetype) {
     209        freetype->ref.ref();
     210    } else {
     211        QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace);
    209212        FT_Face face;
    210213        QFile file(QString::fromUtf8(face_id.filename));
     
    215218            idx.remove(0, 14); // remove ':qmemoryfonts/'
    216219            bool ok = false;
    217             freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
     220            newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
    218221            if (!ok)
    219                 freetype->fontData = QByteArray();
     222                newFreetype->fontData = QByteArray();
    220223        } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
    221224            if (!file.open(QIODevice::ReadOnly)) {
    222                 delete freetype;
    223225                return 0;
    224226            }
    225             freetype->fontData = file.readAll();
    226         }
    227         if (!freetype->fontData.isEmpty()) {
    228             if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)freetype->fontData.constData(), freetype->fontData.size(), face_id.index, &face)) {
    229                 delete freetype;
     227            newFreetype->fontData = file.readAll();
     228        }
     229        if (!newFreetype->fontData.isEmpty()) {
     230            if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
    230231                return 0;
    231232            }
    232233        } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
    233             delete freetype;
    234234            return 0;
    235235        }
    236         freetype->face = face;
    237 
    238         freetype->hbFace = qHBNewFace(face, hb_getSFntTable);
    239         freetype->ref = 0;
    240         freetype->xsize = 0;
    241         freetype->ysize = 0;
    242         freetype->matrix.xx = 0x10000;
    243         freetype->matrix.yy = 0x10000;
    244         freetype->matrix.xy = 0;
    245         freetype->matrix.yx = 0;
    246         freetype->unicode_map = 0;
    247         freetype->symbol_map = 0;
     236        newFreetype->face = face;
     237
     238        newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable);
     239        Q_CHECK_PTR(newFreetype->hbFace);
     240        newFreetype->ref = 1;
     241        newFreetype->xsize = 0;
     242        newFreetype->ysize = 0;
     243        newFreetype->matrix.xx = 0x10000;
     244        newFreetype->matrix.yy = 0x10000;
     245        newFreetype->matrix.xy = 0;
     246        newFreetype->matrix.yx = 0;
     247        newFreetype->unicode_map = 0;
     248        newFreetype->symbol_map = 0;
    248249#ifndef QT_NO_FONTCONFIG
    249         freetype->charset = 0;
    250 #endif
    251 
    252         memset(freetype->cmapCache, 0, sizeof(freetype->cmapCache));
    253 
    254         for (int i = 0; i < freetype->face->num_charmaps; ++i) {
    255             FT_CharMap cm = freetype->face->charmaps[i];
     250        newFreetype->charset = 0;
     251#endif
     252
     253        memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));
     254
     255        for (int i = 0; i < newFreetype->face->num_charmaps; ++i) {
     256            FT_CharMap cm = newFreetype->face->charmaps[i];
    256257            switch(cm->encoding) {
    257258            case FT_ENCODING_UNICODE:
    258                 freetype->unicode_map = cm;
     259                newFreetype->unicode_map = cm;
    259260                break;
    260261            case FT_ENCODING_APPLE_ROMAN:
    261262            case FT_ENCODING_ADOBE_LATIN_1:
    262                 if (!freetype->unicode_map || freetype->unicode_map->encoding != FT_ENCODING_UNICODE)
    263                     freetype->unicode_map = cm;
     263                if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE)
     264                    newFreetype->unicode_map = cm;
    264265                break;
    265266            case FT_ENCODING_ADOBE_CUSTOM:
    266267            case FT_ENCODING_MS_SYMBOL:
    267                 if (!freetype->symbol_map)
    268                     freetype->symbol_map = cm;
     268                if (!newFreetype->symbol_map)
     269                    newFreetype->symbol_map = cm;
    269270                break;
    270271            default:
     
    273274        }
    274275
    275         if (!FT_IS_SCALABLE(freetype->face) && freetype->face->num_fixed_sizes == 1)
    276             FT_Set_Char_Size (face, X_SIZE(freetype->face, 0), Y_SIZE(freetype->face, 0), 0, 0);
     276        if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1)
     277            FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0);
    277278# if 0
    278279        FcChar8 *name;
    279280        FcPatternGetString(pattern, FC_FAMILY, 0, &name);
    280281        qDebug("%s: using maps: default: %x unicode: %x, symbol: %x", name,
    281                freetype->face->charmap ? freetype->face->charmap->encoding : 0,
    282                freetype->unicode_map ? freetype->unicode_map->encoding : 0,
    283                freetype->symbol_map ? freetype->symbol_map->encoding : 0);
     282               newFreetype->face->charmap ? newFreetype->face->charmap->encoding : 0,
     283               newFreetype->unicode_map ? newFreetype->unicode_map->encoding : 0,
     284               newFreetype->symbol_map ? newFreetype->symbol_map->encoding : 0);
    284285
    285286        for (int i = 0; i < 256; i += 8)
    286287            qDebug("    %x: %d %d %d %d %d %d %d %d", i,
    287                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    288                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    289                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    290                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i));
    291 #endif
    292 
    293         FT_Set_Charmap(freetype->face, freetype->unicode_map);
    294         freetypeData->faces.insert(face_id, freetype);
    295     }
    296     freetype->ref.ref();
     288                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     289                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     290                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     291                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i));
     292#endif
     293
     294        FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map);
     295        QT_TRY {
     296            freetypeData->faces.insert(face_id, newFreetype.data());
     297        } QT_CATCH(...) {
     298            newFreetype.take()->release(face_id);
     299            // we could return null in principle instead of throwing
     300            QT_RETHROW;
     301        }
     302        freetype = newFreetype.take();
     303    }
    297304    return freetype;
    298305}
     
    308315            FcCharSetDestroy(charset);
    309316#endif
    310         freetypeData->faces.take(face_id);
     317        if(freetypeData->faces.contains(face_id))
     318            freetypeData->faces.take(face_id);
    311319        delete this;
    312320    }
     
    320328void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing)
    321329{
    322     *ysize = fontDef.pixelSize << 6;
     330    *ysize = qRound(fontDef.pixelSize * 64);
    323331    *xsize = *ysize * fontDef.stretch / 100;
    324332    *outline_drawing = false;
     
    380388        p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender);
    381389        p.emSquare = face->size->metrics.y_ppem;
    382         p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
     390//        p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
     391        p.boundingBox = QRectF(0, -p.ascent.toReal(),
     392                               face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() );
    383393    }
    384394    p.italicAngle = 0;
     
    609619    transform = false;
    610620    antialias = true;
     621    freetype = 0;
    611622    default_load_flags = 0;
    612623    default_hint_style = HintNone;
     
    614625    lcdFilterType = 0;
    615626#if defined(FT_LCD_FILTER_H)
    616     lcdFilterType = (int) FT_LCD_FILTER_DEFAULT;
     627    lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
    617628#endif
    618629    defaultFormat = Format_None;
     
    639650    defaultFormat = format;
    640651    this->antialias = antialias;
     652
    641653    if (!antialias)
    642654        glyphFormat = QFontEngineGlyphCache::Raster_Mono;
     655    else if (format == Format_A8)
     656        glyphFormat = QFontEngineGlyphCache::Raster_A8;
     657    else if (format == Format_A32)
     658        glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
     659
    643660    face_id = faceId;
    644661    freetype = QFreetypeFace::getFace(face_id);
     
    695712
    696713    metrics = face->size->metrics;
     714
    697715#if defined(Q_WS_QWS)
    698716    /*
     
    738756
    739757    // apply our matrix to this, but note that the metrics will not be affected by this.
    740     FT_Matrix matrix = freetype->matrix;
    741758    FT_Face face = lockFace();
    742     matrix = this->matrix;
     759    FT_Matrix matrix = this->matrix;
    743760    FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
    744761    FT_Set_Transform(face, &matrix, 0);
     
    12051222QFixed QFontEngineFT::descent() const
    12061223{
    1207     return QFixed::fromFixed(-metrics.descender);
     1224    // subtract a pixel to work around QFontMetrics's built-in + 1
     1225    return QFixed::fromFixed(-metrics.descender - 64);
    12081226}
    12091227
     
    13811399
    13821400    for (int i = 0; i < num_glyphs; ++i) {
    1383         if (!gs->glyph_data.contains(glyphs[i])
    1384             || gs->glyph_data.value(glyphs[i])->format != format) {
     1401        Glyph *glyph = gs->glyph_data.value(glyphs[i]);
     1402        if (glyph == 0 || glyph->format != format) {
    13851403            if (!face) {
    13861404                face = lockFace();
     
    15211539        return false;
    15221540    }
     1541
     1542#if !defined(QT_NO_FONTCONFIG)
     1543    extern QMutex *qt_fontdatabase_mutex();
     1544    QMutex *mtx = 0;
     1545#endif
    15231546
    15241547    bool mirrored = flags & QTextEngine::RightToLeft;
     
    15341557                glyph_t glyph;
    15351558#if !defined(QT_NO_FONTCONFIG)
     1559                if (!mtx) {
     1560                    mtx = qt_fontdatabase_mutex();
     1561                    mtx->lock();
     1562                }
     1563
    15361564                if (FcCharSetHasChar(freetype->charset, uc)) {
    15371565#else
     
    15621590                uc = QChar::mirroredChar(uc);
    15631591            glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
    1564             if (!glyphs->glyphs[glyph_pos]
     1592            if (!glyphs->glyphs[glyph_pos]) {
    15651593#if !defined(QT_NO_FONTCONFIG)
    1566                 && FcCharSetHasChar(freetype->charset, uc)
    1567 #endif
    1568                 ) {
    1569             redo:
    1570                 glyph_t glyph = FT_Get_Char_Index(face, uc);
    1571                 if (!glyph && (uc == 0xa0 || uc == 0x9)) {
    1572                     uc = 0x20;
    1573                     goto redo;
     1594                if (!mtx) {
     1595                    mtx = qt_fontdatabase_mutex();
     1596                    mtx->lock();
    15741597                }
    1575                 glyphs->glyphs[glyph_pos] = glyph;
    1576                 if (uc < QFreetypeFace::cmapCacheSize)
    1577                     freetype->cmapCache[uc] = glyph;
     1598
     1599                if (FcCharSetHasChar(freetype->charset, uc))
     1600#endif
     1601                {
     1602                redo:
     1603                    glyph_t glyph = FT_Get_Char_Index(face, uc);
     1604                    if (!glyph && (uc == 0xa0 || uc == 0x9)) {
     1605                        uc = 0x20;
     1606                        goto redo;
     1607                    }
     1608                    glyphs->glyphs[glyph_pos] = glyph;
     1609                    if (uc < QFreetypeFace::cmapCacheSize)
     1610                        freetype->cmapCache[uc] = glyph;
     1611                }
    15781612            }
    15791613            ++glyph_pos;
     
    15831617    *nglyphs = glyph_pos;
    15841618    glyphs->numGlyphs = glyph_pos;
     1619
     1620#if !defined(QT_NO_FONTCONFIG)
     1621    if (mtx)
     1622        mtx->unlock();
     1623#endif
    15851624
    15861625    if (flags & QTextEngine::GlyphIndicesOnly)
     
    17891828    GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono;
    17901829
    1791     Glyph *glyph = loadGlyph(g, glyph_format);
    1792     if (!glyph)
    1793         return QImage();
     1830    Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
     1831    if (!glyph) {
     1832        unlockFace();
     1833        return QFontEngine::alphaMapForGlyph(g);
     1834    }
    17941835
    17951836    const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4;
     
    18171858}
    18181859
     1860QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t)
     1861{
     1862    if (t.type() > QTransform::TxTranslate)
     1863        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
     1864
     1865    lockFace();
     1866
     1867    GlyphFormat glyph_format = Format_A32;
     1868
     1869    Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
     1870    if (!glyph) {
     1871        unlockFace();
     1872        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
     1873    }
     1874
     1875    QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
     1876    memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height);
     1877    unlockFace();
     1878
     1879    return img;
     1880}
     1881
    18191882void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
    18201883{
Note: See TracChangeset for help on using the changeset viewer.