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_mac.mm

    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**
     
    120120
    121121
     122
     123void qmacfontengine_gamma_correct(QImage *image)
     124{
     125    extern uchar qt_pow_rgb_gamma[256];
     126
     127    // gamma correct the pixels back to linear color space...
     128    int h = image->height();
     129    int w = image->width();
     130
     131    for (int y=0; y<h; ++y) {
     132        uint *pixels = (uint *) image->scanLine(y);
     133        for (int x=0; x<w; ++x) {
     134            uint p = pixels[x];
     135            uint r = qt_pow_rgb_gamma[qRed(p)];
     136            uint g = qt_pow_rgb_gamma[qGreen(p)];
     137            uint b = qt_pow_rgb_gamma[qBlue(p)];
     138            pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
     139        }
     140    }
     141}
     142
     143
    122144#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
    123145QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
     
    136158        break;
    137159    }
    138    
     160
    139161    QCFString name;
    140162    ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
     163
    141164    QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
    142     QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); 
     165    QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0);
    143166    ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits);
    144167
     
    157180        float zero = 0.0;
    158181        QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
    159         CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern);
     182        CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern);
    160183    }
    161184
     
    163186    fe->ref.ref();
    164187    engines.append(fe);
    165    
     188
    166189}
    167190
     
    177200            return i;
    178201    }
    179    
     202
    180203    QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
    181204    QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that);
     
    228251            const uint fontIndex = (fontIndexForFont(runFont) << 24);
    229252            //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
    230             QVarLengthArray<CGGlyph, 512> cgglyphs(0);           
     253            QVarLengthArray<CGGlyph, 512> cgglyphs(0);
    231254            const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run);
    232255            if (!tmpGlyphs) {
     
    261284                CFIndex k = 0;
    262285                CFIndex i = 0;
    263                 for (i = stringRange.location; 
     286                for (i = stringRange.location;
    264287                     (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
    265288                    if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
     
    382405QFixed QCoreTextFontEngine::descent() const
    383406{
    384     return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
     407    // subtract a pixel to even out the historical +1 in QFontMetrics::height().
     408    // Fix in Qt 5.
     409    return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1;
    385410}
    386411QFixed QCoreTextFontEngine::leading() const
     
    426451    if (glyphs.size() == 0)
    427452        return;
    428    
     453
    429454    CGContextSetFontSize(ctx, fontDef.pixelSize);
    430    
     455
    431456    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    432    
     457
    433458    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
    434    
     459
    435460    CGAffineTransformConcat(cgMatrix, oldTextMatrix);
    436    
     461
    437462    if (synthesisFlags & QFontEngine::SynthesizedItalic)
    438463        cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
    439    
     464
    440465// ###    cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
    441    
     466
    442467    CGContextSetTextMatrix(ctx, cgMatrix);
    443    
     468
    444469    CGContextSetTextDrawingMode(ctx, kCGTextFill);
    445    
    446    
     470
     471
    447472    QVarLengthArray<CGSize> advances(glyphs.size());
    448473    QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
    449    
     474
    450475    for (int i = 0; i < glyphs.size() - 1; ++i) {
    451476        advances[i].width = (positions[i + 1].x - positions[i].x).toReal();
     
    456481    advances[glyphs.size() - 1].height = 0;
    457482    cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1];
    458    
     483
    459484    CGContextSetFont(ctx, cgFont);
    460485    //NSLog(@"Font inDraw %@  ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont));
    461    
     486
    462487    CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
    463    
     488
    464489    CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
    465    
     490
    466491    if (synthesisFlags & QFontEngine::SynthesizedBold) {
    467492        CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
    468493                                 positions[0].y.toReal());
    469        
     494
    470495        CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
    471496    }
    472    
     497
    473498    CGContextSetTextMatrix(ctx, oldTextMatrix);
    474499}
     
    524549
    525550    if (synthesisFlags & QFontEngine::SynthesizedItalic)
    526         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
     551        cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
    527552
    528553
     
    534559}
    535560
    536 QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
     561QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
    537562{
    538563    const glyph_metrics_t br = boundingBox(glyph);
     
    541566
    542567    CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
    543 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    544568    uint cgflags = kCGImageAlphaNoneSkipFirst;
    545569#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
    546     if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
    547         cgflags |= kCGBitmapByteOrder32Host;
    548 #endif
    549 #else
    550     CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
     570    cgflags |= kCGBitmapByteOrder32Host;
    551571#endif
    552572    CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
     
    554574                                             cgflags);
    555575    CGContextSetFontSize(ctx, fontDef.pixelSize);
    556     CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
     576    CGContextSetShouldAntialias(ctx, aa ||
     577                                (fontDef.pointSize > qt_antialiasing_threshold
     578                                 && !(fontDef.styleStrategy & QFont::NoAntialias)));
     579    CGContextSetShouldSmoothFonts(ctx, aa);
    557580    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    558581    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
     
    588611
    589612    CGContextRelease(ctx);
     613
     614    return im;
     615}
     616
     617QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
     618{
     619    QImage im = imageForGlyph(glyph, 0, false);
    590620
    591621    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
     
    608638}
    609639
     640QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x)
     641{
     642    if (x.type() >= QTransform::TxScale)
     643        return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x);
     644
     645    QImage im = imageForGlyph(glyph, margin, true);
     646    qmacfontengine_gamma_correct(&im);
     647    return im;
     648}
     649
    610650void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
    611651{
     
    623663bool QCoreTextFontEngine::canRender(const QChar *string, int len)
    624664{
    625     QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, 
     665    QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont,
    626666                  QCFType<CFStringRef>(CFStringCreateWithCharactersNoCopy(0,
    627667                                                              reinterpret_cast<const UniChar *>(string),
     
    673713        if (fontDef.weight >= QFont::Bold)
    674714            fntStyle |= ::bold;
    675         if (fontDef.style != QFont::StyleNormal) 
     715        if (fontDef.style != QFont::StyleNormal)
    676716            fntStyle |= ::italic;
    677717
     
    793833                           && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
    794834        }
    795         Q_ASSERT(*nfo->numGlyphs == item->length - surrogates);
    796835#endif
    797836        for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop)
     
    819858
    820859        if (glyphId != 0xffff || i == 0) {
    821             nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
    822 
    823             nfo->glyphs->advances_y[i] = yAdvance;
    824             nfo->glyphs->advances_x[i] = xAdvance;
     860            if (i < nfo->glyphs->numGlyphs)
     861            {
     862                nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
     863
     864                nfo->glyphs->advances_y[i] = yAdvance;
     865                nfo->glyphs->advances_x[i] = xAdvance;
     866            }
    825867        } else {
    826868            // ATSUI gives us 0xffff as glyph id at the index in the glyph array for
     
    956998        tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount);
    957999        tmpItem.log_clusters = shaperItem.log_clusters + charIdx;
    958         if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, 
     1000        if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length,
    9591001                                  &tmpItem.glyphs, &glyphCount, flags,
    9601002                                  &tmpItem)) {
     
    9921034    nfo.shaperItem = shaperItem;
    9931035
     1036    int prevNumGlyphs = *nglyphs;
     1037
    9941038    QVarLengthArray<int> mappedFonts(len);
    9951039    for (int i = 0; i < len; ++i)
     
    10181062                                       ;
    10191063
    1020         if (!(flags & QTextEngine::DesignMetrics)) {
    1021             layopts |= kATSLineFractDisable | kATSLineUseDeviceMetrics
    1022                        | kATSLineDisableAutoAdjustDisplayPos;
    1023         }
     1064        layopts |= kATSLineUseDeviceMetrics;
    10241065
    10251066        if (fontDef.styleStrategy & QFont::NoAntialias)
     
    11061147
    11071148    ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning);
     1149    if (prevNumGlyphs < *nfo.numGlyphs)
     1150        return false;
    11081151    return true;
    11091152}
     
    12221265    else
    12231266        transform = CGAffineTransformIdentity;
    1224    
     1267
    12251268    ATSUTextMeasurement metric;
    12261269
    12271270    ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0);
    12281271    m_ascent = FixRound(metric);
    1229    
     1272
    12301273    ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0);
    12311274    m_descent = FixRound(metric);
     
    13661409QFixed QFontEngineMac::descent() const
    13671410{
    1368     return m_descent;
     1411    // subtract a pixel to even out the historical +1 in QFontMetrics::height().
     1412    // Fix in Qt 5.
     1413    return m_descent - 1;
    13691414}
    13701415
     
    14231468}
    14241469
    1425 QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
     1470
     1471/*!
     1472  Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for
     1473  the subpixel antialiasing...
     1474*/
     1475QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful)
    14261476{
    14271477    const glyph_metrics_t br = boundingBox(glyph);
    14281478    QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32);
    1429     im.fill(0);
     1479    im.fill(0xff000000);
    14301480
    14311481    CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
    1432 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    14331482    uint cgflags = kCGImageAlphaNoneSkipFirst;
    14341483#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
    1435     if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
    1436         cgflags |= kCGBitmapByteOrder32Host;
    1437 #endif
    1438 #else
    1439     CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
     1484    cgflags |= kCGBitmapByteOrder32Host;
    14401485#endif
    14411486    CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
     
    14451490    CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
    14461491    // turn off sub-pixel hinting - no support for that in OpenGL
    1447     CGContextSetShouldSmoothFonts(ctx, false);
     1492    CGContextSetShouldSmoothFonts(ctx, colorful);
    14481493    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    14491494    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
     
    14761521
    14771522    CGContextRelease(ctx);
     1523
     1524    return im;
     1525}
     1526
     1527QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
     1528{
     1529    QImage im = imageForGlyph(glyph, 2, false);
    14781530
    14791531    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
     
    14961548}
    14971549
     1550QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
     1551{
     1552    QImage im = imageForGlyph(glyph, margin, true);
     1553
     1554    if (t.type() >= QTransform::TxScale) {
     1555        im = im.transformed(t);
     1556    }
     1557
     1558    qmacfontengine_gamma_correct(&im);
     1559
     1560    return im;
     1561}
     1562
     1563
    14981564bool QFontEngineMac::canRender(const QChar *string, int len)
    14991565{
     
    15641630    FaceId ret;
    15651631#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
     1632if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
    15661633    // CTFontGetPlatformFont
    15671634    FSRef ref;
     
    15711638    ret.index = fontID;
    15721639    FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
    1573 #else
     1640}else
     1641#endif
     1642{
    15741643    FSSpec spec;
    15751644    if (ATSFontGetFileSpecification(FMGetATSFontRefFromFont(fontID), &spec) != noErr)
     
    15811650    ret.index = fontID;
    15821651    FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
    1583 #endif
     1652}
    15841653    return ret;
    15851654}
     
    16491718       lw = qFromBigEndian<quint16>(lw);
    16501719    props.lineWidth = lw;
    1651    
     1720
    16521721    // CTFontCopyPostScriptName
    16531722    QCFString psName;
     
    16641733
    16651734    int emSquare = properties().emSquare.toInt();
    1666    
     1735
    16671736    const int maxAttributeCount = 4;
    16681737    ATSUAttributeTag tags[maxAttributeCount + 1];
     
    16761745    values[attributeCount] = &size;
    16771746    ++attributeCount;
    1678    
     1747
    16791748    Q_ASSERT(attributeCount < maxAttributeCount + 1);
    16801749    OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values);
Note: See TracChangeset for help on using the changeset viewer.