コード例 #1
0
ファイル: qpaintengineex.cpp プロジェクト: Afreeca/qt
void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem)
{
    QPainterPath path;
#ifndef Q_WS_MAC
    path.setFillRule(Qt::WindingFill);
#endif

    if (staticTextItem->numGlyphs == 0)
        return;

    QFontEngine *fontEngine = staticTextItem->fontEngine();
    fontEngine->addGlyphsToPath(staticTextItem->glyphs, staticTextItem->glyphPositions,
                                staticTextItem->numGlyphs, &path, 0);
    if (!path.isEmpty()) {
        QPainterState *s = state();
        QPainter::RenderHints oldHints = s->renderHints;
        bool changedHints = false;
        if (bool(oldHints & QPainter::TextAntialiasing)
            && !bool(fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
            && !bool(oldHints & QPainter::Antialiasing)) {
            s->renderHints |= QPainter::Antialiasing;
            renderHintsChanged();
            changedHints = true;
        }

        fill(qtVectorPathForPath(path), s->pen.color());

        if (changedHints) {
            s->renderHints = oldHints;
            renderHintsChanged();
        }
    }
}
コード例 #2
0
static
QFontEngine *loadEngine(int script, const QFontDef &request,
                        QtFontFamily *family, QtFontFoundry *foundry,
                        QtFontStyle *style, QtFontSize *size)
{

    QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
    //make sure that the db has all fallback families
    if (engine && engine->type() != QFontEngine::Multi
        && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {

        if (family && !family->askedForFallback) {
            QFont::Style fontStyle = QFont::Style(style->key.style);
            QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
            if (styleHint == QFont::AnyStyle && request.fixedPitch)
                styleHint = QFont::TypeWriter;
            family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script));

            family->askedForFallback = true;
        }

        QStringList fallbacks = privateDb()->fallbackFamilies;
        if (family && !family->fallbackFamilies.isEmpty())
            fallbacks = family->fallbackFamilies;

        engine = new QFontEngineMultiQPA(engine, script, fallbacks);

        // Cache Multi font engine as well in case we got the FT single
        // font engine when we are actually looking for a Multi one
        QFontCache::Key key(request, script, 1);
        QFontCache::instance()->instance()->insertEngine(key, engine);
    }

    return engine;
}
コード例 #3
0
ファイル: qfont_x11.cpp プロジェクト: aroraujjwal/qt3
int QFontMetrics::width( QChar ch ) const
{
    unsigned short uc = ch.unicode();
    if ( uc < QFontEngineData::widthCacheSize &&
	 d->engineData && d->engineData->widthCache[ uc ] )
	return d->engineData->widthCache[ uc ];

    if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode()))
	return 0;

    QFont::Script script;
    SCRIPT_FOR_CHAR( script, ch );

    QFontEngine *engine = d->engineForScript( script );
#ifdef QT_CHECK_STATE
    Q_ASSERT( engine != 0 );
#endif // QT_CHECK_STATE

    glyph_t glyphs[8];
    advance_t advances[8];
    int nglyphs = 7;
    engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE );

    // ### can nglyphs != 1 happen at all? Not currently I think
    if ( uc < QFontEngineData::widthCacheSize && advances[0] > 0 && advances[0] < 0x100 )
	d->engineData->widthCache[ uc ] = advances[0];

    return advances[0];
}
コード例 #4
0
ファイル: qfont_x11.cpp プロジェクト: aroraujjwal/qt3
Qt::HANDLE qt_xft_handle(const QFont &font)
{
    QFontEngine *engine = font.d->engineForScript( QFontPrivate::defaultScript );
    if (!engine->type() == QFontEngine::Xft)
        return 0;
    return (long)static_cast<QFontEngineXft *>(engine)->font();
}
コード例 #5
0
static HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric)
{
    if (metric == HB_FontAscent) {
        QFontEngine *fe = (QFontEngine *)font->userData;
        return fe->ascent().value();
    }
    return 0;
}
コード例 #6
0
ファイル: qfont_qws.cpp プロジェクト: Miguel-J/eneboo-core
Qt::HANDLE QFont::handle() const
{
    QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript );
#ifdef QT_CHECK_STATE
    Q_ASSERT( engine != 0 );
#endif // QT_CHECK_STATE

    return engine->handle();
}
コード例 #7
0
ファイル: qfont_mac.cpp プロジェクト: Fale/qtmoko
// Returns an ATSUFonFamilyRef
Qt::HANDLE QFont::handle() const
{
#if 0
    QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
    if (fe && fe->type() == QFontEngine::Mac)
        return (Qt::HANDLE)static_cast<QFontEngineMacMulti*>(fe)->fontFamilyRef();
#endif
    return 0;
}
コード例 #8
0
ファイル: qfont_mac.cpp プロジェクト: 13W/phantomjs
// Returns an ATSUFonFamilyRef
Qt::HANDLE QFont::handle() const
{
#ifdef QT_MAC_USE_COCOA
    QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
    if (fe && fe->type() == QFontEngine::Multi)
        return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID();
#endif
    return 0;
}
コード例 #9
0
ファイル: qfont_x11.cpp プロジェクト: aroraujjwal/qt3
/*!
    Returns the name of the font within the underlying window system.

    On Windows, this is usually just the family name of a TrueType
    font.

    On X11, it is an XLFD (X Logical Font Description).  When Qt is
    build with Xft support on X11, the return value can be an Xft
    pattern or an XLFD.

    Using the return value of this function is usually \e not \e
    portable.

    \sa setRawName()
*/
QString QFont::rawName() const
{
    QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript );
#ifdef QT_CHECK_STATE
    Q_ASSERT( engine != 0 );
#endif // QT_CHECK_STATE

    return QString::fromLatin1( engine->name() );
}
コード例 #10
0
ファイル: qfont_qws.cpp プロジェクト: Miguel-J/eneboo-core
/*!
    \overload

    Returns the width of the first \a len characters of string \a str.
*/
int QFontMetrics::width( const QString &str, int len ) const
{
    if ( len < 0 )
	len = str.length();
    int ret=0;
    QFontEngine *engine = d->engineForScript( QFont::NoScript );
    for (int i=0; i<len; i++)
	ret += memorymanager->lockGlyphMetrics( engine->handle(), str[i].unicode() )->advance;
    return (ret*engine->scale)>>8;
}
コード例 #11
0
ファイル: qfont_x11.cpp プロジェクト: Fale/qtmoko
QString QFont::rawName() const
{
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
    Q_ASSERT(engine != 0);
    if (engine->type() == QFontEngine::Multi)
        engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
    if (engine->type() == QFontEngine::XLFD)
        return QString::fromLatin1(engine->name());
    return QString();
}
コード例 #12
0
ファイル: qfont_x11.cpp プロジェクト: Fale/qtmoko
Qt::HANDLE QFont::handle() const
{
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
    Q_ASSERT(engine != 0);
    if (engine->type() == QFontEngine::Multi)
        engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
    if (engine->type() == QFontEngine::XLFD)
        return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
    return 0;
}
コード例 #13
0
HFONT QFont::handle() const
{
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
    Q_ASSERT(engine != 0);
    if (engine->type() == QFontEngine::Multi)
        engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
    if (engine->type() == QFontEngine::Win)
	return static_cast<QFontEngineWin *>(engine)->hfont;
    return 0;
}
コード例 #14
0
static void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics)
{
    QFontEngine *fe = (QFontEngine *)font->userData;
    glyph_metrics_t m = fe->boundingBox(glyph);
    metrics->x = m.x.value();
    metrics->y = m.y.value();
    metrics->width = m.width.value();
    metrics->height = m.height.value();
    metrics->xOffset = m.xoff.value();
    metrics->yOffset = m.yoff.value();
}
コード例 #15
0
FT_Face QFont::freetypeFace() const
{
#ifndef QT_NO_FREETYPE
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
    if (engine->type() == QFontEngine::Multi)
        engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
    if (engine->type() == QFontEngine::Freetype) {
        const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
        return ft->non_locked_face();
    }
#endif
    return 0;
}
コード例 #16
0
void tst_QFontMetrics::inFontUcs4()
{
    int id = QFontDatabase::addApplicationFont(":/fonts/ucs4font.ttf");
    QVERIFY(id >= 0);

    QFont font("QtTestUcs4");
    {
        QFontMetrics fm(font);
        QVERIFY(fm.inFontUcs4(0x1D7FF));
    }

    {
        QFontMetricsF fm(font);
        QVERIFY(fm.inFontUcs4(0x1D7FF));
    }

    {
        QFontEngine *engine = QFontPrivate::get(font)->engineForScript(QChar::Script_Common);
        QGlyphLayout glyphs;
        glyphs.numGlyphs = 3;
        uint buf[3];
        glyphs.glyphs = buf;

        QString string;
        {
            string.append(QChar::highSurrogate(0x1D7FF));
            string.append(QChar::lowSurrogate(0x1D7FF));

            glyphs.numGlyphs = 3;
            glyphs.glyphs[0] = 0;
            QVERIFY(engine->stringToCMap(string.constData(), string.size(),
                                         &glyphs, &glyphs.numGlyphs,
                                         QFontEngine::GlyphIndicesOnly));
            QCOMPARE(glyphs.numGlyphs, 1);
            QCOMPARE(glyphs.glyphs[0], uint(1));
        }
        {
            string.clear();
            string.append(QChar::ObjectReplacementCharacter);

            glyphs.numGlyphs = 3;
            glyphs.glyphs[0] = 0;
            QVERIFY(engine->stringToCMap(string.constData(), string.size(),
                                         &glyphs, &glyphs.numGlyphs,
                                         QFontEngine::GlyphIndicesOnly));
            QVERIFY(glyphs.glyphs[0] != 1);
        }
    }

    QFontDatabase::removeApplicationFont(id);
}
コード例 #17
0
ファイル: qpf2.cpp プロジェクト: husninazer/qt
QByteArray QPF::generate(const QFont &font, int options, const QList<CharacterRange> &ranges, QString *originalFontFile)
{
    QTextEngine engine("Test", font);
    engine.itemize();
    engine.shape(0);
    QFontEngine *fontEngine = engine.fontEngine(engine.layoutData->items[0]);
    if (fontEngine->type() == QFontEngine::Multi)
        fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(0);

    if (originalFontFile)
        *originalFontFile = QFile::decodeName(fontEngine->faceId().filename);

    return generate(fontEngine, options, ranges);
}
コード例 #18
0
static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags)
{
    QFontEngine *fe = (QFontEngine *)font->userData;

    QVarLengthGlyphLayoutArray qglyphs(numGlyphs);

    for (hb_uint32 i = 0; i < numGlyphs; ++i)
        qglyphs.glyphs[i] = glyphs[i];

    fe->recalcAdvances(&qglyphs, flags & HB_ShaperFlag_UseDesignMetrics ? QFlags<QTextEngine::ShaperFlag>(QTextEngine::DesignMetrics) : QFlags<QTextEngine::ShaperFlag>(0));

    for (hb_uint32 i = 0; i < numGlyphs; ++i)
        advances[i] = qglyphs.advances_x[i].value();
}
コード例 #19
0
ファイル: qfont_x11.cpp プロジェクト: aroraujjwal/qt3
/*!
    Returns the window system handle to the font, for low-level
    access. Using this function is \e not portable.
*/
Qt::HANDLE QFont::handle() const
{
    QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript );
#ifdef QT_CHECK_STATE
    Q_ASSERT( engine != 0 );
#endif // QT_CHECK_STATE

    switch ( engine->type() ) {
    case QFontEngine::XLFD:
	return ((QFontEngineXLFD *) engine)->handle();
    case QFontEngine::LatinXLFD:
	return ((QFontEngineLatinXLFD *) engine)->handle();

    default: break;
    }
    return 0;
}
コード例 #20
0
ファイル: qfont_qws.cpp プロジェクト: Miguel-J/eneboo-core
int QFontMetrics::width( QChar ch ) const
{
    unsigned short uc = ch.unicode();
    QFontEngine *engine = d->engineForScript( QFont::NoScript );
    if ( uc < QFontEngineData::widthCacheSize &&
	 d->engineData && d->engineData->widthCache[ uc ] )
	return (d->engineData->widthCache[ uc ]*engine->scale)>>8;

    if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode()))
	return 0;

    int width = memorymanager->lockGlyphMetrics( engine->handle(), ch.unicode() )->advance;

    if ( ch.unicode() < QFontEngineData::widthCacheSize && width > 0 && width < 0x100 )
	d->engineData->widthCache[ ch.unicode() ] = width;

    return (width*engine->scale)>>8;
}
コード例 #21
0
ファイル: qfont_mac.cpp プロジェクト: Fale/qtmoko
/*!
  Returns an ATSUFontID
*/
quint32 QFont::macFontID() const  // ### need 64-bit version
{
#ifdef QT_MAC_USE_COCOA
    return 0;
#elif 1
    QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
    if (fe && fe->type() == QFontEngine::Multi)
        return static_cast<QFontEngineMacMulti*>(fe)->macFontID();
#else
    Str255 name;
    if(FMGetFontFamilyName((FMFontFamily)((UInt32)handle()), name) == noErr) {
        short fnum;
        GetFNum(name, &fnum);
        return fnum;
    }
#endif
    return 0;
}
コード例 #22
0
QString QSGDistanceFieldGlyphCacheManager::fontKey(const QRawFont &font)
{
    QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
    if (!fe->faceId().filename.isEmpty()) {
        QByteArray keyName = fe->faceId().filename;
        if (font.style() != QFont::StyleNormal)
            keyName += QByteArray(" I");
        if (font.weight() != QFont::Normal)
            keyName += ' ' + QByteArray::number(font.weight());
        keyName += QByteArray(" DF");
        return QString::fromUtf8(keyName);
    } else {
        return QString::fromLatin1("%1_%2_%3_%4")
                  .arg(font.familyName())
                  .arg(font.styleName())
                  .arg(font.weight())
                  .arg(font.style());
    }
}
コード例 #23
0
ファイル: qrawfont.cpp プロジェクト: venkatarajasekhar/Qt
/*!
   Fetches the physical representation based on a \a font query. The physical font returned is
   the font that will be preferred by Qt in order to display text in the selected \a writingSystem.

   \warning This function is potentially expensive and should not be called in performance
   sensitive code.
*/
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
    QRawFont rawFont;
    QFontPrivate *font_d = QFontPrivate::get(font);
    int script = qt_script_for_writing_system(writingSystem);
    QFontEngine *fe = font_d->engineForScript(script);

    if (fe != 0 && fe->type() == QFontEngine::Multi) {
        QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
        fe = multiEngine->engine(0);
        Q_ASSERT(fe);
    }

    if (fe != 0) {
        rawFont.d.data()->setFontEngine(fe);
        rawFont.d.data()->hintingPreference = font.hintingPreference();
    }
    return rawFont;
}
コード例 #24
0
ファイル: qgl_x11.cpp プロジェクト: aroraujjwal/qt3
void QGLContext::generateFontDisplayLists( const QFont & fnt, int listBase )
{
    QFont f(fnt);
    QFontEngine *engine = f.d->engineForScript(QFont::Latin);

#ifndef QT_NO_XFTFREETYPE
    if(engine->type() == QFontEngine::Xft) {
	qgl_use_font((QFontEngineXft *) engine, 0, 256, listBase);
	return;
    }
#endif
    // glXUseXFont() only works with XLFD font structures and a few GL
    // drivers crash if 0 is passed as the font handle
    f.setStyleStrategy(QFont::OpenGLCompatible);
    if (f.handle() && (engine->type() == QFontEngine::XLFD
		       || engine->type() == QFontEngine::LatinXLFD)) {
 	glXUseXFont((Font) f.handle(), 0, 256, listBase);
    }
}
コード例 #25
0
void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
{
    QFont f(fnt);
    QFontEngine *engine = f.d->engineForScript(QUnicodeTables::Common);

    if (engine->type() == QFontEngine::Multi)
        engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
#ifndef QT_NO_FONTCONFIG
    if(engine->type() == QFontEngine::Freetype) {
        qgl_use_font(static_cast<QFontEngineFT *>(engine), 0, 256, listBase);
        return;
    }
#endif
    // glXUseXFont() only works with XLFD font structures and a few GL
    // drivers crash if 0 is passed as the font handle
    f.setStyleStrategy(QFont::OpenGLCompatible);
    if (f.handle() && engine->type() == QFontEngine::XLFD)
        glXUseXFont(static_cast<Font>(f.handle()), 0, 256, listBase);
}
コード例 #26
0
ファイル: qsgcontext.cpp プロジェクト: mortenelund/qt
/*!
    Factory function for scene graph backends of the distance-field glyph cache.
 */
QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &font)
{
    Q_D(QSGContext);

    if (!d->distanceFieldCacheManager)
        d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager;

    QSGDistanceFieldGlyphCache *cache = d->distanceFieldCacheManager->cache(font);
    if (!cache) {
        QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
        if (platformIntegration != 0
            && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) {
            QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
            if (!fe->faceId().filename.isEmpty()) {
                QByteArray keyName = fe->faceId().filename;
                if (font.style() != QFont::StyleNormal)
                    keyName += QByteArray(" I");
                if (font.weight() != QFont::Normal)
                    keyName += ' ' + QByteArray::number(font.weight());
                keyName += QByteArray(" DF");
                QPlatformSharedGraphicsCache *sharedGraphicsCache =
                        platformIntegration->createPlatformSharedGraphicsCache(keyName);

                if (sharedGraphicsCache != 0) {
                    sharedGraphicsCache->ensureCacheInitialized(keyName,
                                                                QPlatformSharedGraphicsCache::OpenGLTexture,
                                                                QPlatformSharedGraphicsCache::Alpha8);

                    cache = new QSGSharedDistanceFieldGlyphCache(keyName,
                                                                sharedGraphicsCache,
                                                                d->distanceFieldCacheManager,
                                                                glContext(),
                                                                font);
                }
            }
        }
        if (!cache)
            cache = new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
        d->distanceFieldCacheManager->insertCache(font, cache);
    }
    return cache;
}
コード例 #27
0
ファイル: qfont_qws.cpp プロジェクト: Miguel-J/eneboo-core
int QFontMetrics::charWidth( const QString &str, int pos ) const
{
    if ( pos < 0 || pos > (int)str.length() )
	return 0;

    const QChar &ch = str.unicode()[ pos ];
    if ( ch.unicode() < QFontEngineData::widthCacheSize &&
	 d->engineData && d->engineData->widthCache[ ch.unicode() ] )
	return (d->engineData->widthCache[ ch.unicode() ]*d->engineData->engine->scale)>>8;

    QFont::Script script;
    SCRIPT_FOR_CHAR( script, ch );

    int width;

    if ( script >= QFont::Arabic && script <= QFont::Khmer ) {
	// complex script shaping. Have to do some hard work
	int from = QMAX( 0,  pos - 8 );
	int to = QMIN( (int)str.length(), pos + 8 );
	QConstString cstr( str.unicode()+from, to-from);
	QTextEngine layout( cstr.string(), d );
	layout.itemize( QTextEngine::WidthOnly );
	width = layout.width( pos-from, 1 );
    } else if ( ::category( ch ) == QChar::Mark_NonSpacing || qIsZeroWidthChar(ch.unicode())) {
        width = 0;
    } else {
	QFontEngine *engine = d->engineForScript( script );
#ifdef QT_CHECK_STATE
	Q_ASSERT( engine != 0 );
#endif // QT_CHECK_STATE

	glyph_t glyphs[8];
	advance_t advances[8];
	int nglyphs = 7;
	engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE );
	width = advances[0];
    }
    if ( ch.unicode() < QFontEngineData::widthCacheSize && width > 0 && width < 0x100 )
	d->engineData->widthCache[ ch.unicode() ] = width;
    return width;
}
コード例 #28
0
static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
{
    QFontEngine *fe = (QFontEngine *)font->userData;

    QVarLengthGlyphLayoutArray qglyphs(*numGlyphs);

    QTextEngine::ShaperFlags shaperFlags(QTextEngine::GlyphIndicesOnly);
    if (rightToLeft)
        shaperFlags |= QTextEngine::RightToLeft;

    int nGlyphs = *numGlyphs;
    bool result = fe->stringToCMap(reinterpret_cast<const QChar *>(string), length, &qglyphs, &nGlyphs, shaperFlags);
    *numGlyphs = nGlyphs;
    if (!result)
        return false;

    for (hb_uint32 i = 0; i < *numGlyphs; ++i)
        glyphs[i] = qglyphs.glyphs[i];

    return true;
}
コード例 #29
0
void QTextEngine::shapeTextMac(int item) const
{
    QScriptItem &si = layoutData->items[item];

    si.glyph_data_offset = layoutData->used;

    QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
    if (font->type() != QFontEngine::Multi) {
        shapeTextWithHarfbuzz(item);
        return;
    }
    
#ifndef QT_MAC_USE_COCOA
    QFontEngineMacMulti *fe = static_cast<QFontEngineMacMulti *>(font);
#else
    QCoreTextFontEngineMulti *fe = static_cast<QCoreTextFontEngineMulti *>(font);
#endif
    QTextEngine::ShaperFlags flags;
    if (si.analysis.bidiLevel % 2)
        flags |= RightToLeft;
    if (option.useDesignMetrics())
	flags |= DesignMetrics;

    attributes(); // pre-initialize char attributes

    const int len = length(item);
    int num_glyphs = length(item);
    const QChar *str = layoutData->string.unicode() + si.position;
    ushort upperCased[256];
    if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
            || si.analysis.flags == QScriptAnalysis::Lowercase) {
        ushort *uc = upperCased;
        if (len > 256)
            uc = new ushort[len];
        for (int i = 0; i < len; ++i) {
            if(si.analysis.flags == QScriptAnalysis::Lowercase)
                uc[i] = str[i].toLower().unicode();
            else
                uc[i] = str[i].toUpper().unicode();
        }
        str = reinterpret_cast<const QChar *>(uc);
    }

    ensureSpace(num_glyphs);
    num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;

    QGlyphLayout g = availableGlyphs(&si);
    g.numGlyphs = num_glyphs;
    unsigned short *log_clusters = logClusters(&si);

    bool stringToCMapFailed = false;
    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
        ensureSpace(num_glyphs);
        stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
                                              attributes());
    }

    if (!stringToCMapFailed) {
        heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);

        si.num_glyphs = num_glyphs;

        layoutData->used += si.num_glyphs;

        QGlyphLayout g = shapedGlyphs(&si);

        if (si.analysis.script == QUnicodeTables::Arabic) {
            QVarLengthArray<QArabicProperties> props(len + 2);
            QArabicProperties *properties = props.data();
            int f = si.position;
            int l = len;
            if (f > 0) {
                --f;
                ++l;
                ++properties;
            }
            if (f + l < layoutData->string.length()) {
                ++l;
            }
            qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());

            unsigned short *log_clusters = logClusters(&si);

            for (int i = 0; i < len; ++i) {
                int gpos = log_clusters[i];
                g.attributes[gpos].justification = properties[i].justification;
            }
        }
    }

    const ushort *uc = reinterpret_cast<const ushort *>(str);

    if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
         || si.analysis.flags == QScriptAnalysis::Lowercase)
        && uc != upperCased)
        delete [] uc;
}
コード例 #30
0
void QFontDatabase::load(const QFontPrivate *d, int script)
{
    // sanity checks
    if(!QFontCache::instance)
        qWarning("QFont: Must construct a QApplication before a QFont");
    Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
    Q_UNUSED(script);

    QFontDef req = d->request;
    req.pixelSize = qt_mac_pixelsize(req, d->dpi);

    // set the point size to 0 to get better caching
    req.pointSize = 0;
    QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen);

    if(!(d->engineData = QFontCache::instance->findEngineData(key))) {
        d->engineData = new QFontEngineData;
        QFontCache::instance->insertEngineData(key, d->engineData);
    } else {
        d->engineData->ref.ref();
    }
    if(d->engineData->engine) // already loaded
        return;

    // set it to the actual pointsize, so QFontInfo will do the right thing
    req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi));

    QFontEngine *e = QFontCache::instance->findEngine(key);
    if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
        e = new QTestFontEngine(req.pixelSize);
        e->fontDef = req;
    }

    if(e) {
        Q_ASSERT(e->type() == QFontEngine::Multi || e->type() == QFontEngine::TestFontEngine);
        e->ref.ref();
        d->engineData->engine = e;
        return; // the font info and fontdef should already be filled
    }

    //find the font
    QStringList family_list = req.family.split(QLatin1Char(','));
    // append the substitute list for each family in family_list
    {
	    QStringList subs_list;
	    for(QStringList::ConstIterator it = family_list.begin(); it != family_list.end(); ++it)
		    subs_list += QFont::substitutes(*it);
	    family_list += subs_list;
    }

    const char *stylehint = styleHint(req);
    if (stylehint)
        family_list << QLatin1String(stylehint);

    // add QFont::defaultFamily() to the list, for compatibility with
    // previous versions
    family_list << QApplication::font().defaultFamily();

    ATSFontFamilyRef familyRef = 0;
    ATSFontRef fontRef = 0;
    QFontDatabasePrivate *db = privateDb();
    if (!db->count)
        initializeDb();
    for(int i = 0; i < family_list.size(); ++i) {
        for (int k = 0; k < db->count; ++k) {
            if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
                QByteArray family_name = db->families[k]->name.toUtf8();
                familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
                if (familyRef) {
                    fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
                    goto FamilyFound;
                }
            }
        }
    }
FamilyFound:
    //fill in the engine's font definition
    QFontDef fontDef = d->request; //copy..
    if(fontDef.pointSize < 0)
	fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
    else
	fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
#if 0
    ItemCount name_count;
    if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) {
        ItemCount actualName_size;
        if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) {
            QByteArray actualName(actualName_size);
            if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size)
                fontDef.family = QString::fromUtf8(actualName);
        }
    }
#else
    {
        QCFString actualName;
        if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
            fontDef.family = actualName;
    }
#endif

    QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
    d->engineData->engine = engine;
    engine->ref.ref(); //a ref for the engineData->engine
    QFontCache::instance->insertEngine(key, engine);
}