~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/text/qfontengine_ft.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
2
**
3
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
 
4
** All rights reserved.
4
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
6
**
6
7
** This file is part of the QtGui module of the Qt Toolkit.
7
8
**
8
9
** $QT_BEGIN_LICENSE:LGPL$
9
 
** Commercial Usage
10
 
** Licensees holding valid Qt Commercial licenses may use this file in
11
 
** accordance with the Qt Commercial License Agreement provided with the
12
 
** Software or, alternatively, in accordance with the terms contained in
13
 
** a written agreement between you and Nokia.
 
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.
14
15
**
15
16
** GNU Lesser General Public License Usage
16
17
** Alternatively, this file may be used under the terms of the GNU Lesser
20
21
** ensure the GNU Lesser General Public License version 2.1 requirements
21
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22
23
**
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.
27
 
**
28
 
** GNU General Public License Usage
29
 
** Alternatively, this file may be used under the terms of the GNU
30
 
** General Public License version 3.0 as published by the Free Software
31
 
** Foundation and appearing in the file LICENSE.GPL included in the
32
 
** packaging of this file.  Please review the following information to
33
 
** ensure the GNU General Public License version 3.0 requirements will be
34
 
** met: http://www.gnu.org/copyleft/gpl.html.
35
 
**
36
 
** If you are unsure which license is appropriate for your use, please
37
 
** contact the sales department at http://www.qtsoftware.com/contact.
 
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
38
** $QT_END_LICENSE$
39
39
**
40
40
****************************************************************************/
54
54
#include <private/qpdf_p.h>
55
55
#include <private/qharfbuzz_p.h>
56
56
 
57
 
#include <private/qpdf_p.h>
58
 
 
59
57
#include "qfontengine_ft_p.h"
60
58
#include <ft2build.h>
61
59
#include FT_FREETYPE_H
193
191
/*
194
192
 * One font file can contain more than one font (bold/italic for example)
195
193
 * 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)
196
197
 */
197
198
QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id)
198
199
{
204
205
        FT_Init_FreeType(&freetypeData->library);
205
206
 
206
207
    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);
209
212
        FT_Face face;
210
213
        QFile file(QString::fromUtf8(face_id.filename));
211
214
        if (face_id.filename.startsWith(":qmemoryfonts/")) {
214
217
            QByteArray idx = face_id.filename;
215
218
            idx.remove(0, 14); // remove ':qmemoryfonts/'
216
219
            bool ok = false;
217
 
            freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
 
220
            newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
218
221
            if (!ok)
219
 
                freetype->fontData = QByteArray();
 
222
                newFreetype->fontData = QByteArray();
220
223
        } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
221
224
            if (!file.open(QIODevice::ReadOnly)) {
222
 
                delete freetype;
223
225
                return 0;
224
226
            }
225
 
            freetype->fontData = file.readAll();
 
227
            newFreetype->fontData = file.readAll();
226
228
        }
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;
 
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)) {
230
231
                return 0;
231
232
            }
232
233
        } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
233
 
            delete freetype;
234
234
            return 0;
235
235
        }
236
 
        freetype->face = face;
 
236
        newFreetype->face = face;
237
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;
 
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;
248
249
#ifndef QT_NO_FONTCONFIG
249
 
        freetype->charset = 0;
 
250
        newFreetype->charset = 0;
250
251
#endif
251
252
 
252
 
        memset(freetype->cmapCache, 0, sizeof(freetype->cmapCache));
 
253
        memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));
253
254
 
254
 
        for (int i = 0; i < freetype->face->num_charmaps; ++i) {
255
 
            FT_CharMap cm = freetype->face->charmaps[i];
 
255
        for (int i = 0; i < newFreetype->face->num_charmaps; ++i) {
 
256
            FT_CharMap cm = newFreetype->face->charmaps[i];
256
257
            switch(cm->encoding) {
257
258
            case FT_ENCODING_UNICODE:
258
 
                freetype->unicode_map = cm;
 
259
                newFreetype->unicode_map = cm;
259
260
                break;
260
261
            case FT_ENCODING_APPLE_ROMAN:
261
262
            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;
264
265
                break;
265
266
            case FT_ENCODING_ADOBE_CUSTOM:
266
267
            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;
269
270
                break;
270
271
            default:
271
272
                break;
272
273
            }
273
274
        }
274
275
 
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);
277
278
# if 0
278
279
        FcChar8 *name;
279
280
        FcPatternGetString(pattern, FC_FAMILY, 0, &name);
280
281
        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);
284
285
 
285
286
        for (int i = 0; i < 256; i += 8)
286
287
            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));
 
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));
291
292
#endif
292
293
 
293
 
        FT_Set_Charmap(freetype->face, freetype->unicode_map);
294
 
        freetypeData->faces.insert(face_id, freetype);
 
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();
295
303
    }
296
 
    freetype->ref.ref();
297
304
    return freetype;
298
305
}
299
306
 
307
314
        if (charset)
308
315
            FcCharSetDestroy(charset);
309
316
#endif
310
 
        freetypeData->faces.take(face_id);
 
317
        if(freetypeData->faces.contains(face_id))
 
318
            freetypeData->faces.take(face_id);
311
319
        delete this;
312
320
    }
313
321
    if (freetypeData->faces.isEmpty()) {
608
616
    kerning_pairs_loaded = false;
609
617
    transform = false;
610
618
    antialias = true;
 
619
    freetype = 0;
611
620
    default_load_flags = 0;
612
621
    default_hint_style = HintNone;
613
622
    subpixelType = Subpixel_None;
638
647
{
639
648
    defaultFormat = format;
640
649
    this->antialias = antialias;
 
650
 
641
651
    if (!antialias)
642
652
        glyphFormat = QFontEngineGlyphCache::Raster_Mono;
 
653
    else if (format == Format_A8)
 
654
        glyphFormat = QFontEngineGlyphCache::Raster_A8;
 
655
    else if (format == Format_A32)
 
656
        glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
 
657
 
643
658
    face_id = faceId;
644
659
    freetype = QFreetypeFace::getFace(face_id);
645
660
    if (!freetype) {
1380
1395
    FT_Face face = 0;
1381
1396
 
1382
1397
    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) {
 
1398
        Glyph *glyph = gs->glyph_data.value(glyphs[i]);
 
1399
        if (glyph == 0 || glyph->format != format) {
1385
1400
            if (!face) {
1386
1401
                face = lockFace();
1387
1402
                FT_Matrix m = matrix;
1839
1854
    return img;
1840
1855
}
1841
1856
 
 
1857
QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t)
 
1858
{
 
1859
    if (t.type() > QTransform::TxTranslate)
 
1860
        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
 
1861
 
 
1862
    lockFace();
 
1863
 
 
1864
    GlyphFormat glyph_format = Format_A32;
 
1865
 
 
1866
    Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
 
1867
    if (!glyph) {
 
1868
        unlockFace();
 
1869
        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
 
1870
    }
 
1871
 
 
1872
    QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
 
1873
    memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height);
 
1874
    unlockFace();
 
1875
 
 
1876
    return img;
 
1877
}
 
1878
 
1842
1879
void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
1843
1880
{
1844
1881
    delete defaultGlyphSet.glyph_data.take(glyph);