diff options
Diffstat (limited to 'src/gui/text/windows/qwindowsfontengine.cpp')
-rw-r--r-- | src/gui/text/windows/qwindowsfontengine.cpp | 147 |
1 files changed, 46 insertions, 101 deletions
diff --git a/src/gui/text/windows/qwindowsfontengine.cpp b/src/gui/text/windows/qwindowsfontengine.cpp index cbf50f65da..5de80dc8a3 100644 --- a/src/gui/text/windows/qwindowsfontengine.cpp +++ b/src/gui/text/windows/qwindowsfontengine.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qwindowsfontengine_p.h" #include "qwindowsnativeimage_p.h" @@ -74,6 +38,9 @@ QT_BEGIN_NAMESPACE +QT_IMPL_METATYPE_EXTERN(HFONT) +QT_IMPL_METATYPE_EXTERN(LOGFONT) + //### mingw needed define #ifndef TT_PRIM_CSPLINE #define TT_PRIM_CSPLINE 3 @@ -89,23 +56,11 @@ QT_BEGIN_NAMESPACE // common DC for all fonts -typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); -static PtrGetCharWidthI ptrGetCharWidthI = 0; -static bool resolvedGetCharWidthI = false; - -static void resolveGetCharWidthI() -{ - if (resolvedGetCharWidthI) - return; - resolvedGetCharWidthI = true; - ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI"); -} - // general font engine QFixed QWindowsFontEngine::lineThickness() const { - if(lineWidth > 0) + if (lineWidth > 0) return lineWidth; return QFontEngine::lineThickness(); @@ -149,7 +104,7 @@ void QWindowsFontEngine::getCMap() SelectObject(hdc, hfont); bool symb = false; if (ttf) { - cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); + cmapTable = getSfntTable(QFont::Tag("cmap").value()); cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symb, &cmapSize); } @@ -160,7 +115,7 @@ void QWindowsFontEngine::getCMap() symbol = symb; designToDevice = 1; _faceId.index = 0; - if(cmap) { + if (cmap) { OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); unitsPerEm = int(otm->otmEMSquare); const QFixed unitsPerEmF(unitsPerEm); @@ -177,8 +132,9 @@ void QWindowsFontEngine::getCMap() } } -int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const +int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, int *mappedGlyphs) const { + *mappedGlyphs = 0; int glyph_pos = 0; { if (symbol) { @@ -186,8 +142,10 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa while (it.hasNext()) { const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); - if(!glyphs->glyphs[glyph_pos] && uc < 0x100) + if (!glyphs->glyphs[glyph_pos] && uc < 0x100) glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000); + if (glyphs->glyphs[glyph_pos] || isIgnorableChar(uc)) + (*mappedGlyphs)++; ++glyph_pos; } } else if (ttf) { @@ -195,6 +153,8 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa while (it.hasNext()) { const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); + if (glyphs->glyphs[glyph_pos] || isIgnorableChar(uc)) + (*mappedGlyphs)++; ++glyph_pos; } } else { @@ -205,6 +165,8 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa glyphs->glyphs[glyph_pos] = uc; else glyphs->glyphs[glyph_pos] = 0; + if (glyphs->glyphs[glyph_pos] || isIgnorableChar(uc)) + (*mappedGlyphs)++; ++glyph_pos; } } @@ -252,16 +214,6 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; getCMap(); - if (!resolvedGetCharWidthI) - resolveGetCharWidthI(); - - // ### Properties accessed by QWin32PrintEngine (QtPrintSupport) - QVariantMap userData; - userData.insert(QStringLiteral("logFont"), QVariant::fromValue(m_logfont)); - userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont)); - userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf))); - setUserData(userData); - hasUnreliableOutline = (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) == 0; } @@ -314,7 +266,7 @@ HGDIOBJ QWindowsFontEngine::selectDesignFont() const return SelectObject(m_fontEngineData->hdc, designFont); } -bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const +int QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { Q_ASSERT(glyphs->numGlyphs >= *nglyphs); if (*nglyphs < len) { @@ -323,18 +275,18 @@ bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *g } glyphs->numGlyphs = *nglyphs; - *nglyphs = getGlyphIndexes(str, len, glyphs); + int mappedGlyphs; + *nglyphs = getGlyphIndexes(str, len, glyphs, &mappedGlyphs); if (!(flags & GlyphIndicesOnly)) recalcAdvances(glyphs, flags); - return true; + return mappedGlyphs; } inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width) { - if (ptrGetCharWidthI) - ptrGetCharWidthI(hdc, glyph, 1, 0, &width); + GetCharWidthI(hdc, glyph, 1, 0, &width); } void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const @@ -344,7 +296,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape if (ttf && (flags & DesignMetrics)) { for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; - if(int(glyph) >= designAdvancesSize) { + if (int(glyph) >= designAdvancesSize) { const int newSize = int(glyph + 256) >> 8 << 8; designAdvances = reinterpret_cast<QFixed *>(realloc(designAdvances, size_t(newSize) * sizeof(QFixed))); Q_CHECK_PTR(designAdvances); @@ -362,7 +314,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape } glyphs->advances[i] = designAdvances[glyph]; } - if(oldFont) + if (oldFont) DeleteObject(SelectObject(hdc, oldFont)); } else { for(int i = 0; i < glyphs->numGlyphs; i++) { @@ -383,7 +335,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape oldFont = SelectObject(hdc, hfont); if (!ttf) { - QChar ch[2] = { ushort(glyph), 0 }; + QChar ch[2] = { ushort(glyph), u'\0' }; int chrLen = 1; if (QChar::requiresSurrogates(glyph)) { ch[0] = QChar::highSurrogate(glyph); @@ -408,18 +360,6 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape } } -glyph_metrics_t QWindowsFontEngine::boundingBox(const QGlyphLayout &glyphs) -{ - if (glyphs.numGlyphs == 0) - return glyph_metrics_t(); - - QFixed w = 0; - for (int i = 0; i < glyphs.numGlyphs; ++i) - w += glyphs.effectiveAdvance(i); - - return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0); -} - bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const { Q_ASSERT(metrics != 0); @@ -539,7 +479,7 @@ namespace { QFixed QWindowsFontEngine::capHeight() const { - const QByteArray tableData = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + const QByteArray tableData = getSfntTable(QFont::Tag("OS/2").value()); if (size_t(tableData.size()) >= sizeof(OS2Table)) { const OS2Table *table = reinterpret_cast<const OS2Table *>(tableData.constData()); if (qFromBigEndian<quint16>(table->version) >= 2) { @@ -553,7 +493,7 @@ QFixed QWindowsFontEngine::capHeight() const QFixed QWindowsFontEngine::xHeight() const { - if(x_height >= 0) + if (x_height >= 0) return x_height; return QFontEngine::xHeight(); } @@ -642,7 +582,7 @@ qreal QWindowsFontEngine::minRightBearing() const HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); if (ttf) { - ABC *abc = 0; + ABC *abc = nullptr; int n = tm.tmLastChar - tm.tmFirstChar; if (n <= max_font_count) { abc = new ABC[n+1]; @@ -682,8 +622,8 @@ qreal QWindowsFontEngine::minRightBearing() const fmr = qMin(fmr,abc[i].abcfC); } } - ml = int(fml - 0.9999); - mr = int(fmr - 0.9999); + ml = qFloor(fml); + mr = qFloor(fmr); delete [] abc; } lbearing = ml; @@ -706,7 +646,7 @@ static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale, qreal stretc #endif static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, - QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, + QPainterPath *path, bool ttf, glyph_metrics_t *metric = nullptr, qreal scale = 1.0, qreal stretch = 1.0) { MAT2 mat; @@ -844,7 +784,7 @@ void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions void QWindowsFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) { - if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { + if (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { hasOutline = true; QFontEngine::addOutlineToPath(x, y, glyphs, path, flags); if (hasOutline) { @@ -868,9 +808,9 @@ QT_END_INCLUDE_NAMESPACE int QWindowsFontEngine::synthesized() const { - if(synthesized_flags == -1) { + if (synthesized_flags == -1) { synthesized_flags = 0; - if(ttf) { + if (ttf) { const DWORD HEAD = MAKE_LITTLE_ENDIAN_TAG('h', 'e', 'a', 'd'); HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); @@ -927,7 +867,7 @@ void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gly LOGFONT lf = m_logfont; lf.lfHeight = -unitsPerEm; int flags = synthesized(); - if(flags & SynthesizedItalic) + if (flags & SynthesizedItalic) lf.lfItalic = false; lf.lfWidth = 0; HFONT hf = CreateFontIndirect(&lf); @@ -1050,7 +990,10 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, return ni; } -glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat format) +glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, + const QFixedPoint &, + const QTransform &matrix, + GlyphFormat format) { int margin = 0; if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB) @@ -1115,7 +1058,9 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo #define SPI_GETFONTSMOOTHINGCONTRAST 0x200C #define SPI_SETFONTSMOOTHINGCONTRAST 0x200D -QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTransform &t) +QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, + const QFixedPoint &, + const QTransform &t) { HFONT font = hfont; @@ -1152,9 +1097,9 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const { QFontDef request = fontDef; - QString actualFontName = request.family; + QString actualFontName = request.families.constFirst(); if (!uniqueFamilyName.isEmpty()) - request.family = uniqueFamilyName; + request.families = QStringList(uniqueFamilyName); request.pixelSize = pixelSize; const QString faceName = QString::fromWCharArray(m_logfont.lfFaceName); @@ -1163,7 +1108,7 @@ QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const QWindowsFontDatabase::defaultVerticalDPI(), m_fontEngineData); if (fontEngine) { - fontEngine->fontDef.family = actualFontName; + fontEngine->fontDef.families = QStringList(actualFontName); if (!uniqueFamilyName.isEmpty()) { static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName); if (QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration()) { @@ -1188,7 +1133,7 @@ void QWindowsFontEngine::initFontInfo(const QFontDef &request, SelectObject(dc, hfont); wchar_t n[64]; GetTextFace(dc, 64, n); - fontDef.family = QString::fromWCharArray(n); + fontDef.families = QStringList(QString::fromWCharArray(n)); fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (fontDef.pointSize < 0) { fontDef.pointSize = fontDef.pixelSize * 72. / dpi; |