Implement vertical subpixel positioning where available
For some use cases, vertical subpixel positioning may be useful, as it allows you to vertically align text with other painting primitives. This does impose an overhead, so we make it opt-int with a render hint on the painter. Note that this is only supported on Freetype currently. It might be possible to support on older macOS versions, prior to Mojave (which has disabled subpixel positioning entirely), but since it would have limited usefulness and Freetype is cross-platform anyway, I skipped that. Note: This drive-by-fixes an issue with subpixel positioning where glyphs would always be offset by 1/64, because we added the aliasing offset *after* we had determined the closest subpixel position. The idea of this, as far as I can understand, is rather to snap to nearest subpixel position upwards, not to add an offset to all glyphs, so it should be added before finding the correct position. It had a subtle visual effect when animating the position. It might be that we could get rid of it entirely, as I haven't been able to reproduce any issues with that, but I have moved it instead, to match what I believe the intention was. [ChangeLog][QtGui][Text] Added render hint flag QPainter::VerticalSubpixelPositioning which will position text at subpixel positions vertically whenever supported. In absence of this, text position will be rounded vertically as before. Fixes: QTBUG-35682 Change-Id: I8ce7a72a64e5a0924dac7c244e3e07c2938bfd09 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
80e87ca05c
commit
d79a9b1a4f
@ -196,6 +196,10 @@ struct QFixedPoint {
|
|||||||
constexpr static QFixedPoint fromPointF(const QPointF &p) {
|
constexpr static QFixedPoint fromPointF(const QPointF &p) {
|
||||||
return QFixedPoint(QFixed::fromReal(p.x()), QFixed::fromReal(p.y()));
|
return QFixedPoint(QFixed::fromReal(p.x()), QFixed::fromReal(p.y()));
|
||||||
}
|
}
|
||||||
|
constexpr inline bool operator==(const QFixedPoint &other) const
|
||||||
|
{
|
||||||
|
return x == other.x && y == other.y;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Q_DECLARE_TYPEINFO(QFixedPoint, Q_PRIMITIVE_TYPE);
|
Q_DECLARE_TYPEINFO(QFixedPoint, Q_PRIMITIVE_TYPE);
|
||||||
|
|
||||||
|
@ -766,7 +766,7 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
|
|||||||
bool((painter()->renderHints() & QPainter::TextAntialiasing)
|
bool((painter()->renderHints() & QPainter::TextAntialiasing)
|
||||||
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
|
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
|
||||||
for (int i = 0; i < ti.glyphs.numGlyphs; ++i) {
|
for (int i = 0; i < ti.glyphs.numGlyphs; ++i) {
|
||||||
QImage glyph = ti.fontEngine->bitmapForGlyph(glyphs[i], QFixed(), QTransform());
|
QImage glyph = ti.fontEngine->bitmapForGlyph(glyphs[i], QFixedPoint(), QTransform());
|
||||||
painter()->drawImage(positions[i].x.toReal(), positions[i].y.toReal(), glyph);
|
painter()->drawImage(positions[i].x.toReal(), positions[i].y.toReal(), glyph);
|
||||||
}
|
}
|
||||||
painter()->restore();
|
painter()->restore();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
@ -2812,6 +2812,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||||||
Q_D(QRasterPaintEngine);
|
Q_D(QRasterPaintEngine);
|
||||||
QRasterPaintEngineState *s = state();
|
QRasterPaintEngineState *s = state();
|
||||||
|
|
||||||
|
bool verticalSubPixelPositions = fontEngine->supportsVerticalSubPixelPositions()
|
||||||
|
&& (s->renderHints & QPainter::VerticalSubpixelPositioning) != 0;
|
||||||
|
|
||||||
if (fontEngine->hasInternalCaching()) {
|
if (fontEngine->hasInternalCaching()) {
|
||||||
QFontEngine::GlyphFormat neededFormat =
|
QFontEngine::GlyphFormat neededFormat =
|
||||||
painter()->device()->devType() == QInternal::Widget
|
painter()->device()->devType() == QInternal::Widget
|
||||||
@ -2822,7 +2825,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||||||
neededFormat = QFontEngine::Format_Mono;
|
neededFormat = QFontEngine::Format_Mono;
|
||||||
|
|
||||||
for (int i = 0; i < numGlyphs; i++) {
|
for (int i = 0; i < numGlyphs; i++) {
|
||||||
QFixed spp = fontEngine->subPixelPositionForX(positions[i].x);
|
QFixedPoint spp = fontEngine->subPixelPositionFor(positions[i]);
|
||||||
|
if (!verticalSubPixelPositions)
|
||||||
|
spp.y = 0;
|
||||||
|
|
||||||
const QFontEngine::Glyph *alphaMap = fontEngine->glyphData(glyphs[i], spp, neededFormat, s->matrix);
|
const QFontEngine::Glyph *alphaMap = fontEngine->glyphData(glyphs[i], spp, neededFormat, s->matrix);
|
||||||
if (!alphaMap)
|
if (!alphaMap)
|
||||||
@ -2847,9 +2852,13 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QFixed y = verticalSubPixelPositions
|
||||||
|
? qFloor(positions[i].y)
|
||||||
|
: qRound(positions[i].y);
|
||||||
|
|
||||||
alphaPenBlt(alphaMap->data, bytesPerLine, depth,
|
alphaPenBlt(alphaMap->data, bytesPerLine, depth,
|
||||||
qFloor(positions[i].x) + alphaMap->x,
|
qFloor(positions[i].x) + alphaMap->x,
|
||||||
qRound(positions[i].y) - alphaMap->y,
|
qFloor(y) - alphaMap->y,
|
||||||
alphaMap->width, alphaMap->height,
|
alphaMap->width, alphaMap->height,
|
||||||
fontEngine->expectsGammaCorrectedBlending());
|
fontEngine->expectsGammaCorrectedBlending());
|
||||||
}
|
}
|
||||||
@ -2864,7 +2873,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||||||
fontEngine->setGlyphCache(nullptr, cache);
|
fontEngine->setGlyphCache(nullptr, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->populate(fontEngine, numGlyphs, glyphs, positions);
|
cache->populate(fontEngine, numGlyphs, glyphs, positions, s->renderHints);
|
||||||
cache->fillInPendingGlyphs();
|
cache->fillInPendingGlyphs();
|
||||||
|
|
||||||
const QImage &image = cache->image();
|
const QImage &image = cache->image();
|
||||||
@ -2881,15 +2890,20 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||||||
int margin = fontEngine->glyphMargin(glyphFormat);
|
int margin = fontEngine->glyphMargin(glyphFormat);
|
||||||
const uchar *bits = image.bits();
|
const uchar *bits = image.bits();
|
||||||
for (int i=0; i<numGlyphs; ++i) {
|
for (int i=0; i<numGlyphs; ++i) {
|
||||||
|
QFixedPoint subPixelPosition = fontEngine->subPixelPositionFor(positions[i]);
|
||||||
|
if (!verticalSubPixelPositions)
|
||||||
|
subPixelPosition.y = 0;
|
||||||
|
|
||||||
QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x);
|
|
||||||
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
|
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
|
||||||
const QTextureGlyphCache::Coord &c = cache->coords[glyph];
|
const QTextureGlyphCache::Coord &c = cache->coords[glyph];
|
||||||
if (c.isNull())
|
if (c.isNull())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int x = qFloor(positions[i].x) + c.baseLineX - margin;
|
int x = qFloor(positions[i].x) + c.baseLineX - margin;
|
||||||
int y = qRound(positions[i].y) - c.baseLineY - margin;
|
int y = (verticalSubPixelPositions
|
||||||
|
? qFloor(positions[i].y)
|
||||||
|
: qRound(positions[i].y));
|
||||||
|
y -= c.baseLineY + margin;
|
||||||
|
|
||||||
// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
|
// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
|
||||||
// c.x, c.y,
|
// c.x, c.y,
|
||||||
|
@ -1429,6 +1429,16 @@ void QPainterPrivate::updateState(QPainterState *newState)
|
|||||||
a smooth pixmap transformation algorithm (such as bilinear) rather
|
a smooth pixmap transformation algorithm (such as bilinear) rather
|
||||||
than nearest neighbor.
|
than nearest neighbor.
|
||||||
|
|
||||||
|
\value VerticalSubpixelPositioning Allow text to be positioned at fractions
|
||||||
|
of pixels vertically as well as horizontally, if this is supported by the
|
||||||
|
font engine. This is currently supported by Freetype on all platforms when
|
||||||
|
the hinting preference is QFont::PreferNoHinting, and also on macOS. For
|
||||||
|
most use cases this will not improve visual quality, but may increase memory
|
||||||
|
consumption and some reduction in text rendering performance. Therefore, enabling
|
||||||
|
this is not recommended unless the use case requires it. One such use case could
|
||||||
|
be aligning glyphs with other visual primitives.
|
||||||
|
This value was added in Qt 6.1.
|
||||||
|
|
||||||
\value LosslessImageRendering Use a lossless image rendering, whenever possible.
|
\value LosslessImageRendering Use a lossless image rendering, whenever possible.
|
||||||
Currently, this hint is only used when QPainter is employed to output a PDF
|
Currently, this hint is only used when QPainter is employed to output a PDF
|
||||||
file through QPrinter or QPdfWriter, where drawImage()/drawPixmap() calls
|
file through QPrinter or QPdfWriter, where drawImage()/drawPixmap() calls
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
Antialiasing = 0x01,
|
Antialiasing = 0x01,
|
||||||
TextAntialiasing = 0x02,
|
TextAntialiasing = 0x02,
|
||||||
SmoothPixmapTransform = 0x04,
|
SmoothPixmapTransform = 0x04,
|
||||||
|
VerticalSubpixelPositioning = 0x08,
|
||||||
LosslessImageRendering = 0x40,
|
LosslessImageRendering = 0x40,
|
||||||
};
|
};
|
||||||
Q_FLAG(RenderHint)
|
Q_FLAG(RenderHint)
|
||||||
|
@ -64,7 +64,7 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
|
|||||||
QImage images[NumSubpixelPositions];
|
QImage images[NumSubpixelPositions];
|
||||||
int numImages = 0;
|
int numImages = 0;
|
||||||
for (int i = 0; i < NumSubpixelPositions; ++i) {
|
for (int i = 0; i < NumSubpixelPositions; ++i) {
|
||||||
QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0));
|
QImage img = textureMapForGlyph(glyph, QFixedPoint(QFixed::fromReal(i / 12.0), 0));
|
||||||
|
|
||||||
if (numImages == 0) {
|
if (numImages == 0) {
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
@ -92,8 +92,11 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
|
|||||||
return numImages;
|
return numImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
|
bool QTextureGlyphCache::populate(QFontEngine *fontEngine,
|
||||||
const QFixedPoint *positions)
|
int numGlyphs,
|
||||||
|
const glyph_t *glyphs,
|
||||||
|
const QFixedPoint *positions,
|
||||||
|
QPainter::RenderHints renderHints)
|
||||||
{
|
{
|
||||||
#ifdef CACHE_DEBUG
|
#ifdef CACHE_DEBUG
|
||||||
printf("Populating with %d glyphs\n", numGlyphs);
|
printf("Populating with %d glyphs\n", numGlyphs);
|
||||||
@ -105,6 +108,8 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
|
|||||||
const int paddingDoubled = padding * 2;
|
const int paddingDoubled = padding * 2;
|
||||||
|
|
||||||
bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
|
bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
|
||||||
|
bool verticalSubPixelPositions = fontEngine->supportsVerticalSubPixelPositions()
|
||||||
|
&& (renderHints & QPainter::VerticalSubpixelPositioning) != 0;
|
||||||
if (fontEngine->m_subPixelPositionCount == 0) {
|
if (fontEngine->m_subPixelPositionCount == 0) {
|
||||||
if (!supportsSubPixelPositions) {
|
if (!supportsSubPixelPositions) {
|
||||||
fontEngine->m_subPixelPositionCount = 1;
|
fontEngine->m_subPixelPositionCount = 1;
|
||||||
@ -127,10 +132,12 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
|
|||||||
for (int i=0; i < numGlyphs; ++i) {
|
for (int i=0; i < numGlyphs; ++i) {
|
||||||
const glyph_t glyph = glyphs[i];
|
const glyph_t glyph = glyphs[i];
|
||||||
|
|
||||||
QFixed subPixelPosition;
|
QFixedPoint subPixelPosition;
|
||||||
if (supportsSubPixelPositions) {
|
if (supportsSubPixelPositions) {
|
||||||
QFixed x = positions != nullptr ? positions[i].x : QFixed();
|
QFixedPoint pos = positions != nullptr ? positions[i] : QFixedPoint();
|
||||||
subPixelPosition = fontEngine->subPixelPositionForX(x);
|
subPixelPosition = fontEngine->subPixelPositionFor(pos);
|
||||||
|
if (!verticalSubPixelPositions)
|
||||||
|
subPixelPosition.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
|
if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
|
||||||
@ -263,7 +270,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
|
|||||||
m_pendingGlyphs.clear();
|
m_pendingGlyphs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
|
QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition) const
|
||||||
{
|
{
|
||||||
switch (m_format) {
|
switch (m_format) {
|
||||||
case QFontEngine::Format_A32:
|
case QFontEngine::Format_A32:
|
||||||
@ -317,7 +324,9 @@ void QImageTextureGlyphCache::createTextureData(int width, int height)
|
|||||||
m_image.fill(0);
|
m_image.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition)
|
void QImageTextureGlyphCache::fillTexture(const Coord &c,
|
||||||
|
glyph_t g,
|
||||||
|
const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
QImage mask = textureMapForGlyph(g, subPixelPosition);
|
QImage mask = textureMapForGlyph(g, subPixelPosition);
|
||||||
|
|
||||||
|
@ -83,7 +83,8 @@ public:
|
|||||||
|
|
||||||
struct GlyphAndSubPixelPosition
|
struct GlyphAndSubPixelPosition
|
||||||
{
|
{
|
||||||
GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
|
GlyphAndSubPixelPosition(glyph_t g, const QFixedPoint &spp)
|
||||||
|
: glyph(g), subPixelPosition(spp) {}
|
||||||
|
|
||||||
bool operator==(const GlyphAndSubPixelPosition &other) const
|
bool operator==(const GlyphAndSubPixelPosition &other) const
|
||||||
{
|
{
|
||||||
@ -91,7 +92,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
glyph_t glyph;
|
glyph_t glyph;
|
||||||
QFixed subPixelPosition;
|
QFixedPoint subPixelPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Coord {
|
struct Coord {
|
||||||
@ -109,8 +110,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
|
bool populate(QFontEngine *fontEngine,
|
||||||
const QFixedPoint *positions);
|
int numGlyphs,
|
||||||
|
const glyph_t *glyphs,
|
||||||
|
const QFixedPoint *positions,
|
||||||
|
QPainter::RenderHints renderHints = QPainter::RenderHints());
|
||||||
bool hasPendingGlyphs() const { return !m_pendingGlyphs.isEmpty(); }
|
bool hasPendingGlyphs() const { return !m_pendingGlyphs.isEmpty(); }
|
||||||
void fillInPendingGlyphs();
|
void fillInPendingGlyphs();
|
||||||
|
|
||||||
@ -119,7 +123,9 @@ public:
|
|||||||
virtual int glyphPadding() const { return 0; }
|
virtual int glyphPadding() const { return 0; }
|
||||||
|
|
||||||
virtual void beginFillTexture() { }
|
virtual void beginFillTexture() { }
|
||||||
virtual void fillTexture(const Coord &coord, glyph_t glyph, QFixed subPixelPosition) = 0;
|
virtual void fillTexture(const Coord &coord,
|
||||||
|
glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition) = 0;
|
||||||
virtual void endFillTexture() { }
|
virtual void endFillTexture() { }
|
||||||
|
|
||||||
inline void createCache(int width, int height) {
|
inline void createCache(int width, int height) {
|
||||||
@ -141,7 +147,7 @@ public:
|
|||||||
virtual int maxTextureWidth() const { return QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH; }
|
virtual int maxTextureWidth() const { return QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH; }
|
||||||
virtual int maxTextureHeight() const { return -1; }
|
virtual int maxTextureHeight() const { return -1; }
|
||||||
|
|
||||||
QImage textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const;
|
QImage textureMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int calculateSubPixelPositionCount(glyph_t) const;
|
int calculateSubPixelPositionCount(glyph_t) const;
|
||||||
@ -156,9 +162,12 @@ protected:
|
|||||||
int m_currentRowHeight; // Height of last row
|
int m_currentRowHeight; // Height of last row
|
||||||
};
|
};
|
||||||
|
|
||||||
inline size_t qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g)
|
inline size_t qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g, size_t seed = 0)
|
||||||
{
|
{
|
||||||
return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
|
return qHashMulti(seed,
|
||||||
|
g.glyph,
|
||||||
|
g.subPixelPosition.x.value(),
|
||||||
|
g.subPixelPosition.y.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -171,7 +180,9 @@ public:
|
|||||||
|
|
||||||
virtual void createTextureData(int width, int height) override;
|
virtual void createTextureData(int width, int height) override;
|
||||||
virtual void resizeTextureData(int width, int height) override;
|
virtual void resizeTextureData(int width, int height) override;
|
||||||
virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override;
|
virtual void fillTexture(const Coord &c,
|
||||||
|
glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition) override;
|
||||||
|
|
||||||
inline const QImage &image() const { return m_image; }
|
inline const QImage &image() const { return m_image; }
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ static void qcoretextfontengine_scaleMetrics(glyph_metrics_t &br, const QTransfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, GlyphFormat format)
|
glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &matrix, GlyphFormat format)
|
||||||
{
|
{
|
||||||
if (matrix.type() > QTransform::TxScale)
|
if (matrix.type() > QTransform::TxScale)
|
||||||
return QFontEngine::alphaMapBoundingBox(glyph, subPixelPosition, matrix, format);
|
return QFontEngine::alphaMapBoundingBox(glyph, subPixelPosition, matrix, format);
|
||||||
@ -713,7 +713,7 @@ qreal QCoreTextFontEngine::fontSmoothingGamma()
|
|||||||
return 2.0;
|
return 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, const QColor &color)
|
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &matrix, const QColor &color)
|
||||||
{
|
{
|
||||||
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
|
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
|
||||||
|
|
||||||
@ -773,8 +773,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
|
|||||||
cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMakeScale(matrix.m11(), matrix.m22()));
|
cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMakeScale(matrix.m11(), matrix.m22()));
|
||||||
|
|
||||||
CGGlyph cgGlyph = glyph;
|
CGGlyph cgGlyph = glyph;
|
||||||
qreal pos_x = -br.x.truncate() + subPixelPosition.toReal();
|
|
||||||
qreal pos_y = im.height() + br.y.toReal();
|
qreal pos_x = -br.x.truncate() + subPixelPosition.x.toReal();
|
||||||
|
qreal pos_y = im.height() + br.y.toReal() - subPixelPosition.y.toReal();
|
||||||
|
|
||||||
if (!hasColorGlyphs()) {
|
if (!hasColorGlyphs()) {
|
||||||
CGContextSetTextMatrix(ctx, cgMatrix);
|
CGContextSetTextMatrix(ctx, cgMatrix);
|
||||||
@ -817,12 +818,12 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
|
|||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
|
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
|
return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &x)
|
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &x)
|
||||||
{
|
{
|
||||||
if (x.type() > QTransform::TxScale)
|
if (x.type() > QTransform::TxScale)
|
||||||
return QFontEngine::alphaMapForGlyph(glyph, subPixelPosition, x);
|
return QFontEngine::alphaMapForGlyph(glyph, subPixelPosition, x);
|
||||||
@ -844,7 +845,7 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosit
|
|||||||
return alphaMap;
|
return alphaMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &x)
|
QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &x)
|
||||||
{
|
{
|
||||||
if (x.type() > QTransform::TxScale)
|
if (x.type() > QTransform::TxScale)
|
||||||
return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, x);
|
return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, x);
|
||||||
@ -852,7 +853,7 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo
|
|||||||
return imageForGlyph(glyph, subPixelPosition, x);
|
return imageForGlyph(glyph, subPixelPosition, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color)
|
QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color)
|
||||||
{
|
{
|
||||||
if (t.type() > QTransform::TxScale)
|
if (t.type() > QTransform::TxScale)
|
||||||
return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t, color);
|
return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t, color);
|
||||||
|
@ -91,7 +91,8 @@ public:
|
|||||||
bool canRender(const QChar *string, int len) const override;
|
bool canRender(const QChar *string, int len) const override;
|
||||||
|
|
||||||
int synthesized() const override { return synthesisFlags; }
|
int synthesized() const override { return synthesisFlags; }
|
||||||
bool supportsSubPixelPositions() const override { return true; }
|
bool supportsHorizontalSubPixelPositions() const override { return true; }
|
||||||
|
bool supportsVerticalSubPixelPositions() const override { return false; }
|
||||||
|
|
||||||
QFixed lineThickness() const override;
|
QFixed lineThickness() const override;
|
||||||
QFixed underlinePosition() const override;
|
QFixed underlinePosition() const override;
|
||||||
@ -101,11 +102,11 @@ public:
|
|||||||
FaceId faceId() const override;
|
FaceId faceId() const override;
|
||||||
bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const override;
|
bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const override;
|
||||||
void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
|
void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
|
||||||
QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition) override;
|
QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition) override;
|
||||||
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
|
QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
|
QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override;
|
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &, const QTransform &matrix, GlyphFormat) override;
|
||||||
QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
|
QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color) override;
|
||||||
QFixed emSquareSize() const override;
|
QFixed emSquareSize() const override;
|
||||||
void doKerning(QGlyphLayout *g, ShaperFlags flags) const override;
|
void doKerning(QGlyphLayout *g, ShaperFlags flags) const override;
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
QCoreTextFontEngine(const QFontDef &def);
|
QCoreTextFontEngine(const QFontDef &def);
|
||||||
void init();
|
void init();
|
||||||
QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m, const QColor &color = QColor());
|
QImage imageForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &m, const QColor &color = QColor());
|
||||||
void loadAdvancesForGlyphs(QVarLengthArray<CGGlyph> &cgGlyphs, QGlyphLayout *glyphs) const;
|
void loadAdvancesForGlyphs(QVarLengthArray<CGGlyph> &cgGlyphs, QGlyphLayout *glyphs) const;
|
||||||
bool hasColorGlyphs() const;
|
bool hasColorGlyphs() const;
|
||||||
bool shouldAntialias() const;
|
bool shouldAntialias() const;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
@ -943,7 +943,7 @@ static inline void transformBoundingBox(int *left, int *top, int *right, int *bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
GlyphFormat format,
|
GlyphFormat format,
|
||||||
bool fetchMetricsOnly,
|
bool fetchMetricsOnly,
|
||||||
bool disableOutlineDrawing) const
|
bool disableOutlineDrawing) const
|
||||||
@ -967,8 +967,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
|||||||
FT_Matrix matrix = freetype->matrix;
|
FT_Matrix matrix = freetype->matrix;
|
||||||
|
|
||||||
FT_Vector v;
|
FT_Vector v;
|
||||||
v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.value());
|
v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.x.value());
|
||||||
v.y = 0;
|
v.y = format == Format_Mono ? 0 : FT_Pos(-subPixelPosition.y.value());
|
||||||
FT_Set_Transform(face, &matrix, &v);
|
FT_Set_Transform(face, &matrix, &v);
|
||||||
|
|
||||||
bool hsubpixel = false;
|
bool hsubpixel = false;
|
||||||
@ -1644,7 +1644,11 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
|
|||||||
} else {
|
} else {
|
||||||
if (!face)
|
if (!face)
|
||||||
face = lockFace();
|
face = lockFace();
|
||||||
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs->glyphs[i], 0, Format_None, true);
|
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr,
|
||||||
|
glyphs->glyphs[i],
|
||||||
|
QFixedPoint(),
|
||||||
|
Format_None,
|
||||||
|
true);
|
||||||
if (g)
|
if (g)
|
||||||
glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
|
glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
|
||||||
else
|
else
|
||||||
@ -1685,7 +1689,11 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
|
|||||||
if (!g) {
|
if (!g) {
|
||||||
if (!face)
|
if (!face)
|
||||||
face = lockFace();
|
face = lockFace();
|
||||||
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs.glyphs[i], 0, Format_None, true);
|
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr,
|
||||||
|
glyphs.glyphs[i],
|
||||||
|
QFixedPoint(),
|
||||||
|
Format_None,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
if (g) {
|
if (g) {
|
||||||
QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
|
QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
|
||||||
@ -1730,7 +1738,11 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
|
|||||||
Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : nullptr;
|
Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : nullptr;
|
||||||
if (!g) {
|
if (!g) {
|
||||||
face = lockFace();
|
face = lockFace();
|
||||||
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, 0, Format_None, true);
|
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr,
|
||||||
|
glyph,
|
||||||
|
QFixedPoint(),
|
||||||
|
Format_None,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
if (g) {
|
if (g) {
|
||||||
overall.x = g->x;
|
overall.x = g->x;
|
||||||
@ -1762,10 +1774,13 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
|
|||||||
|
|
||||||
glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matrix)
|
glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matrix)
|
||||||
{
|
{
|
||||||
return alphaMapBoundingBox(glyph, 0, matrix, QFontEngine::Format_None);
|
return alphaMapBoundingBox(glyph, QFixedPoint(), matrix, QFontEngine::Format_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format)
|
glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &matrix,
|
||||||
|
QFontEngine::GlyphFormat format)
|
||||||
{
|
{
|
||||||
Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true);
|
Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true);
|
||||||
|
|
||||||
@ -1828,8 +1843,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex, QFixed subPixelPosition,
|
QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex,
|
||||||
QFontEngine::GlyphFormat neededFormat, const QTransform &t)
|
const QFixedPoint &subPixelPosition,
|
||||||
|
QFontEngine::GlyphFormat neededFormat,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
Q_ASSERT(cacheEnabled);
|
Q_ASSERT(cacheEnabled);
|
||||||
|
|
||||||
@ -1854,7 +1871,7 @@ static inline bool is2dRotation(const QTransform &t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
|
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
GlyphFormat format,
|
GlyphFormat format,
|
||||||
const QTransform &t,
|
const QTransform &t,
|
||||||
bool fetchBoundingBox,
|
bool fetchBoundingBox,
|
||||||
@ -1882,12 +1899,14 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
|
|||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
|
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
return alphaMapForGlyph(g, subPixelPosition, QTransform());
|
return alphaMapForGlyph(g, subPixelPosition, QTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
|
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono;
|
const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono;
|
||||||
|
|
||||||
@ -1902,7 +1921,9 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
|
QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
if (t.type() > QTransform::TxRotate)
|
if (t.type() > QTransform::TxRotate)
|
||||||
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
||||||
@ -1923,7 +1944,10 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co
|
|||||||
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t, const QColor &color)
|
QImage QFontEngineFT::bitmapForGlyph(glyph_t g,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t,
|
||||||
|
const QColor &color)
|
||||||
{
|
{
|
||||||
Q_UNUSED(color);
|
Q_UNUSED(color);
|
||||||
|
|
||||||
@ -1952,7 +1976,7 @@ QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const Q
|
|||||||
|
|
||||||
void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
|
void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
|
||||||
{
|
{
|
||||||
defaultGlyphSet.removeGlyphFromCache(glyph, 0);
|
defaultGlyphSet.removeGlyphFromCache(glyph, QFixedPoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
int QFontEngineFT::glyphCount() const
|
int QFontEngineFT::glyphCount() const
|
||||||
@ -2033,7 +2057,8 @@ void QFontEngineFT::QGlyphSet::clear()
|
|||||||
glyph_data.clear();
|
glyph_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPixelPosition)
|
void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index,
|
||||||
|
const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
if (useFastGlyphData(index, subPixelPosition)) {
|
if (useFastGlyphData(index, subPixelPosition)) {
|
||||||
if (fast_glyph_data[index]) {
|
if (fast_glyph_data[index]) {
|
||||||
@ -2047,7 +2072,9 @@ void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QFontEngineFT::QGlyphSet::setGlyph(glyph_t index, QFixed subPixelPosition, Glyph *glyph)
|
void QFontEngineFT::QGlyphSet::setGlyph(glyph_t index,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
Glyph *glyph)
|
||||||
{
|
{
|
||||||
if (useFastGlyphData(index, subPixelPosition)) {
|
if (useFastGlyphData(index, subPixelPosition)) {
|
||||||
if (!fast_glyph_data[index])
|
if (!fast_glyph_data[index])
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
@ -143,7 +143,7 @@ public:
|
|||||||
|
|
||||||
struct GlyphAndSubPixelPosition
|
struct GlyphAndSubPixelPosition
|
||||||
{
|
{
|
||||||
GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
|
GlyphAndSubPixelPosition(glyph_t g, const QFixedPoint spp) : glyph(g), subPixelPosition(spp) {}
|
||||||
|
|
||||||
bool operator==(const GlyphAndSubPixelPosition &other) const
|
bool operator==(const GlyphAndSubPixelPosition &other) const
|
||||||
{
|
{
|
||||||
@ -151,7 +151,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
glyph_t glyph;
|
glyph_t glyph;
|
||||||
QFixed subPixelPosition;
|
QFixedPoint subPixelPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QGlyphSet
|
struct QGlyphSet
|
||||||
@ -161,13 +161,14 @@ public:
|
|||||||
FT_Matrix transformationMatrix;
|
FT_Matrix transformationMatrix;
|
||||||
bool outline_drawing;
|
bool outline_drawing;
|
||||||
|
|
||||||
void removeGlyphFromCache(glyph_t index, QFixed subPixelPosition);
|
void removeGlyphFromCache(glyph_t index, const QFixedPoint &subPixelPosition);
|
||||||
void clear();
|
void clear();
|
||||||
inline bool useFastGlyphData(glyph_t index, QFixed subPixelPosition) const {
|
inline bool useFastGlyphData(glyph_t index, const QFixedPoint &subPixelPosition) const {
|
||||||
return (index < 256 && subPixelPosition == 0);
|
return (index < 256 && subPixelPosition.x == 0 && subPixelPosition.y == 0);
|
||||||
}
|
}
|
||||||
inline Glyph *getGlyph(glyph_t index, QFixed subPixelPosition = 0) const;
|
inline Glyph *getGlyph(glyph_t index,
|
||||||
void setGlyph(glyph_t index, QFixed spp, Glyph *glyph);
|
const QFixedPoint &subPixelPositionX = QFixedPoint()) const;
|
||||||
|
void setGlyph(glyph_t index, const QFixedPoint &spp, Glyph *glyph);
|
||||||
|
|
||||||
inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
|
inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
|
||||||
inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
|
inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
|
||||||
@ -182,12 +183,17 @@ private:
|
|||||||
QFontEngine::FaceId faceId() const override;
|
QFontEngine::FaceId faceId() const override;
|
||||||
QFontEngine::Properties properties() const override;
|
QFontEngine::Properties properties() const override;
|
||||||
QFixed emSquareSize() const override;
|
QFixed emSquareSize() const override;
|
||||||
bool supportsSubPixelPositions() const override
|
bool supportsHorizontalSubPixelPositions() const override
|
||||||
{
|
{
|
||||||
return default_hint_style == HintLight ||
|
return default_hint_style == HintLight ||
|
||||||
default_hint_style == HintNone;
|
default_hint_style == HintNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool supportsVerticalSubPixelPositions() const override
|
||||||
|
{
|
||||||
|
return supportsHorizontalSubPixelPositions();
|
||||||
|
}
|
||||||
|
|
||||||
bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
|
bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
|
||||||
int synthesized() const override;
|
int synthesized() const override;
|
||||||
|
|
||||||
@ -219,17 +225,19 @@ private:
|
|||||||
glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) override;
|
glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) override;
|
||||||
|
|
||||||
void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const override;
|
void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const override;
|
||||||
QImage alphaMapForGlyph(glyph_t g) override { return alphaMapForGlyph(g, 0); }
|
QImage alphaMapForGlyph(glyph_t g) override { return alphaMapForGlyph(g, QFixedPoint()); }
|
||||||
QImage alphaMapForGlyph(glyph_t, QFixed) override;
|
QImage alphaMapForGlyph(glyph_t, const QFixedPoint &) override;
|
||||||
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
|
QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
|
QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
|
QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color) override;
|
||||||
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
|
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
const QTransform &matrix,
|
const QTransform &matrix,
|
||||||
QFontEngine::GlyphFormat format) override;
|
QFontEngine::GlyphFormat format) override;
|
||||||
Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition,
|
Glyph *glyphData(glyph_t glyph,
|
||||||
GlyphFormat neededFormat, const QTransform &t) override;
|
const QFixedPoint &subPixelPosition,
|
||||||
|
GlyphFormat neededFormat,
|
||||||
|
const QTransform &t) override;
|
||||||
bool hasInternalCaching() const override { return cacheEnabled; }
|
bool hasInternalCaching() const override { return cacheEnabled; }
|
||||||
bool expectsGammaCorrectedBlending() const override;
|
bool expectsGammaCorrectedBlending() const override;
|
||||||
|
|
||||||
@ -252,10 +260,24 @@ private:
|
|||||||
inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
|
inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
|
||||||
inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); }
|
inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); }
|
||||||
|
|
||||||
inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const
|
inline Glyph *loadGlyph(uint glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
GlyphFormat format = Format_None,
|
||||||
|
bool fetchMetricsOnly = false,
|
||||||
|
bool disableOutlineDrawing = false) const
|
||||||
{ return loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); }
|
{ return loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); }
|
||||||
Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const;
|
Glyph *loadGlyph(QGlyphSet *set,
|
||||||
Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false, bool disableOutlineDrawing = false);
|
uint glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
GlyphFormat = Format_None,
|
||||||
|
bool fetchMetricsOnly = false,
|
||||||
|
bool disableOutlineDrawing = false) const;
|
||||||
|
Glyph *loadGlyphFor(glyph_t g,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
GlyphFormat format,
|
||||||
|
const QTransform &t,
|
||||||
|
bool fetchBoundingBox = false,
|
||||||
|
bool disableOutlineDrawing = false);
|
||||||
|
|
||||||
QGlyphSet *loadGlyphSet(const QTransform &matrix);
|
QGlyphSet *loadGlyphSet(const QTransform &matrix);
|
||||||
|
|
||||||
@ -341,12 +363,16 @@ private:
|
|||||||
Q_DECLARE_TYPEINFO(QFontEngineFT::QGlyphSet, Q_RELOCATABLE_TYPE);
|
Q_DECLARE_TYPEINFO(QFontEngineFT::QGlyphSet, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
|
|
||||||
inline size_t qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g)
|
inline size_t qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g, size_t seed)
|
||||||
{
|
{
|
||||||
return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
|
return qHashMulti(seed,
|
||||||
|
g.glyph,
|
||||||
|
g.subPixelPosition.x.value(),
|
||||||
|
g.subPixelPosition.y.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QFontEngineFT::Glyph *QFontEngineFT::QGlyphSet::getGlyph(glyph_t index, QFixed subPixelPosition) const
|
inline QFontEngineFT::Glyph *QFontEngineFT::QGlyphSet::getGlyph(glyph_t index,
|
||||||
|
const QFixedPoint &subPixelPosition) const
|
||||||
{
|
{
|
||||||
if (useFastGlyphData(index, subPixelPosition))
|
if (useFastGlyphData(index, subPixelPosition))
|
||||||
return fast_glyph_data[index];
|
return fast_glyph_data[index];
|
||||||
|
@ -780,7 +780,7 @@ bool qt_fontHasNarrowOutlines(QFontEngine *fontEngine)
|
|||||||
|
|
||||||
const glyph_t glyph = fe->glyphIndex('O');
|
const glyph_t glyph = fe->glyphIndex('O');
|
||||||
if (glyph != 0)
|
if (glyph != 0)
|
||||||
im = fe->alphaMapForGlyph(glyph, QFixed(), QTransform());
|
im = fe->alphaMapForGlyph(glyph, QFixedPoint(), QTransform());
|
||||||
|
|
||||||
Q_ASSERT(fe->ref.loadRelaxed() == 0);
|
Q_ASSERT(fe->ref.loadRelaxed() == 0);
|
||||||
delete fe;
|
delete fe;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
@ -796,7 +796,7 @@ void QFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int n
|
|||||||
addBitmapFontToPath(x, y, g, path, flags);
|
addBitmapFontToPath(x, y, g, path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/)
|
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QFixedPoint &/*subPixelPosition*/)
|
||||||
{
|
{
|
||||||
// For font engines don't support subpixel positioning
|
// For font engines don't support subpixel positioning
|
||||||
return alphaMapForGlyph(glyph);
|
return alphaMapForGlyph(glyph);
|
||||||
@ -812,9 +812,9 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
|
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &t)
|
||||||
{
|
{
|
||||||
if (! supportsSubPixelPositions())
|
if (!supportsHorizontalSubPixelPositions() && !supportsVerticalSubPixelPositions())
|
||||||
return alphaMapForGlyph(glyph, t);
|
return alphaMapForGlyph(glyph, t);
|
||||||
|
|
||||||
QImage i = alphaMapForGlyph(glyph, subPixelPosition);
|
QImage i = alphaMapForGlyph(glyph, subPixelPosition);
|
||||||
@ -825,7 +825,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, con
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t)
|
QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, const QFixedPoint &/*subPixelPosition*/, const QTransform &t)
|
||||||
{
|
{
|
||||||
const QImage alphaMask = alphaMapForGlyph(glyph, t);
|
const QImage alphaMask = alphaMapForGlyph(glyph, t);
|
||||||
QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);
|
QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32);
|
||||||
@ -842,32 +842,37 @@ QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition
|
|||||||
return rgbMask;
|
return rgbMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&, const QColor &)
|
QImage QFontEngine::bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform&, const QColor &)
|
||||||
{
|
{
|
||||||
Q_UNUSED(subPixelPosition);
|
Q_UNUSED(subPixelPosition);
|
||||||
|
|
||||||
return QImage();
|
return QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
QFixed QFontEngine::subPixelPositionForX(QFixed x) const
|
QFixedPoint QFontEngine::subPixelPositionFor(const QFixedPoint &position) const
|
||||||
{
|
{
|
||||||
if (m_subPixelPositionCount <= 1 || !supportsSubPixelPositions())
|
if (m_subPixelPositionCount <= 1
|
||||||
return QFixed();
|
|| (!supportsHorizontalSubPixelPositions()
|
||||||
|
&& !supportsVerticalSubPixelPositions())) {
|
||||||
QFixed subPixelPosition;
|
return QFixedPoint();
|
||||||
if (x != 0) {
|
|
||||||
subPixelPosition = x - x.floor();
|
|
||||||
QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
|
|
||||||
|
|
||||||
// Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over
|
|
||||||
// the lower boundary for the selected rasterization by adding 1/64.
|
|
||||||
subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);
|
|
||||||
}
|
|
||||||
return subPixelPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QFontEngine::Glyph *QFontEngine::glyphData(glyph_t, QFixed,
|
auto f = [&](QFixed v) {
|
||||||
QFontEngine::GlyphFormat, const QTransform &)
|
if (v != 0) {
|
||||||
|
v = v - v.floor() + QFixed::fromFixed(1);
|
||||||
|
QFixed fraction = (v / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
|
||||||
|
v = fraction / QFixed(m_subPixelPositionCount);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
return QFixedPoint(f(position.x), f(position.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
QFontEngine::Glyph *QFontEngine::glyphData(glyph_t,
|
||||||
|
const QFixedPoint &,
|
||||||
|
QFontEngine::GlyphFormat,
|
||||||
|
const QTransform &)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -2215,7 +2220,7 @@ QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph)
|
|||||||
return engine(which)->alphaMapForGlyph(stripped(glyph));
|
return engine(which)->alphaMapForGlyph(stripped(glyph));
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
|
QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
const int which = highByte(glyph);
|
const int which = highByte(glyph);
|
||||||
return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
|
return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
|
||||||
@ -2227,13 +2232,17 @@ QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
|
|||||||
return engine(which)->alphaMapForGlyph(stripped(glyph), t);
|
return engine(which)->alphaMapForGlyph(stripped(glyph), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
|
QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
const int which = highByte(glyph);
|
const int which = highByte(glyph);
|
||||||
return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
|
return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
|
QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
const int which = highByte(glyph);
|
const int which = highByte(glyph);
|
||||||
return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t);
|
return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
@ -176,8 +176,17 @@ public:
|
|||||||
SynthesizedStretch = 0x4
|
SynthesizedStretch = 0x4
|
||||||
};
|
};
|
||||||
virtual int synthesized() const { return 0; }
|
virtual int synthesized() const { return 0; }
|
||||||
virtual bool supportsSubPixelPositions() const { return false; }
|
inline bool supportsSubPixelPositions() const
|
||||||
virtual QFixed subPixelPositionForX(QFixed x) const;
|
{
|
||||||
|
return supportsHorizontalSubPixelPositions() || supportsVerticalSubPixelPositions();
|
||||||
|
}
|
||||||
|
virtual bool supportsHorizontalSubPixelPositions() const { return false; }
|
||||||
|
virtual bool supportsVerticalSubPixelPositions() const { return false; }
|
||||||
|
virtual QFixedPoint subPixelPositionFor(const QFixedPoint &position) const;
|
||||||
|
QFixed subPixelPositionForX(const QFixed &x) const
|
||||||
|
{
|
||||||
|
return subPixelPositionFor(QFixedPoint(x, 0)).x;
|
||||||
|
}
|
||||||
|
|
||||||
virtual QFixed emSquareSize() const { return ascent(); }
|
virtual QFixed emSquareSize() const { return ascent(); }
|
||||||
|
|
||||||
@ -201,15 +210,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
// ### Refactor this into a smaller and more flexible API.
|
// ### Refactor this into a smaller and more flexible API.
|
||||||
virtual QImage alphaMapForGlyph(glyph_t);
|
virtual QImage alphaMapForGlyph(glyph_t);
|
||||||
virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
|
virtual QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition);
|
||||||
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
|
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
|
||||||
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
|
virtual QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t);
|
||||||
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
|
virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t);
|
||||||
virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor());
|
virtual QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color = QColor());
|
||||||
virtual Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
|
virtual Glyph *glyphData(glyph_t glyph, const QFixedPoint &subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
|
||||||
virtual bool hasInternalCaching() const { return false; }
|
virtual bool hasInternalCaching() const { return false; }
|
||||||
|
|
||||||
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
|
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &/*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
|
||||||
{
|
{
|
||||||
return boundingBox(glyph, matrix);
|
return boundingBox(glyph, matrix);
|
||||||
}
|
}
|
||||||
@ -472,10 +481,10 @@ public:
|
|||||||
virtual QFixed xHeight() const override;
|
virtual QFixed xHeight() const override;
|
||||||
virtual QFixed averageCharWidth() const override;
|
virtual QFixed averageCharWidth() const override;
|
||||||
virtual QImage alphaMapForGlyph(glyph_t) override;
|
virtual QImage alphaMapForGlyph(glyph_t) override;
|
||||||
virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override;
|
virtual QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition) override;
|
||||||
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t) override;
|
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t) override;
|
||||||
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
|
virtual QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
|
virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override;
|
||||||
|
|
||||||
virtual QFixed lineThickness() const override;
|
virtual QFixed lineThickness() const override;
|
||||||
virtual QFixed underlinePosition() const override;
|
virtual QFixed underlinePosition() const override;
|
||||||
|
@ -281,12 +281,12 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias
|
|||||||
return QImage();
|
return QImage();
|
||||||
|
|
||||||
if (d->fontEngine->glyphFormat == QFontEngine::Format_ARGB)
|
if (d->fontEngine->glyphFormat == QFontEngine::Format_ARGB)
|
||||||
return d->fontEngine->bitmapForGlyph(glyphIndex, QFixed(), transform);
|
return d->fontEngine->bitmapForGlyph(glyphIndex, QFixedPoint(), transform);
|
||||||
|
|
||||||
if (antialiasingType == SubPixelAntialiasing)
|
if (antialiasingType == SubPixelAntialiasing)
|
||||||
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), transform);
|
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixedPoint(), transform);
|
||||||
|
|
||||||
return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
|
return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixedPoint(), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1736,7 +1736,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
|
|||||||
g.glyphs[i] |= (engineIdx << 24);
|
g.glyphs[i] |= (engineIdx << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!actualFontEngine->supportsSubPixelPositions()) {
|
if (!actualFontEngine->supportsHorizontalSubPixelPositions()) {
|
||||||
for (uint i = 0; i < num_glyphs; ++i)
|
for (uint i = 0; i < num_glyphs; ++i)
|
||||||
g.advances[i] = g.advances[i].round();
|
g.advances[i] = g.advances[i].round();
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1043,10 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
|
|||||||
return ni;
|
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;
|
int margin = 0;
|
||||||
if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
|
if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
|
||||||
@ -1108,7 +1111,9 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo
|
|||||||
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
|
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
|
||||||
#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
|
#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;
|
HFONT font = hfont;
|
||||||
|
|
||||||
|
@ -107,8 +107,13 @@ public:
|
|||||||
|
|
||||||
QImage alphaMapForGlyph(glyph_t t) override { return alphaMapForGlyph(t, QTransform()); }
|
QImage alphaMapForGlyph(glyph_t t) override { return alphaMapForGlyph(t, QTransform()); }
|
||||||
QImage alphaMapForGlyph(glyph_t, const QTransform &xform) override;
|
QImage alphaMapForGlyph(glyph_t, const QTransform &xform) override;
|
||||||
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override;
|
QImage alphaRGBMapForGlyph(glyph_t t,
|
||||||
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override;
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &xform) override;
|
||||||
|
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
|
||||||
|
const QFixedPoint &,
|
||||||
|
const QTransform &matrix,
|
||||||
|
GlyphFormat) override;
|
||||||
|
|
||||||
QFontEngine *cloneWithSize(qreal pixelSize) const override;
|
QFontEngine *cloneWithSize(qreal pixelSize) const override;
|
||||||
Qt::HANDLE handle() const override;
|
Qt::HANDLE handle() const override;
|
||||||
|
@ -602,7 +602,9 @@ qreal QWindowsFontEngineDirectWrite::maxCharWidth() const
|
|||||||
return m_maxAdvanceWidth.toReal();
|
return m_maxAdvanceWidth.toReal();
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
|
QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t)
|
||||||
{
|
{
|
||||||
QImage im = imageForGlyph(glyph, subPixelPosition, glyphMargin(Format_A8), t);
|
QImage im = imageForGlyph(glyph, subPixelPosition, glyphMargin(Format_A8), t);
|
||||||
|
|
||||||
@ -621,18 +623,19 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed sub
|
|||||||
return alphaMap;
|
return alphaMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
|
QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
|
return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
|
bool QWindowsFontEngineDirectWrite::supportsHorizontalSubPixelPositions() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
int margin,
|
int margin,
|
||||||
const QTransform &originalTransform,
|
const QTransform &originalTransform,
|
||||||
const QColor &color)
|
const QColor &color)
|
||||||
@ -659,7 +662,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
|||||||
xform.scale(fontDef.stretch / 100.0, 1.0);
|
xform.scale(fontDef.stretch / 100.0, 1.0);
|
||||||
|
|
||||||
DWRITE_MATRIX transform;
|
DWRITE_MATRIX transform;
|
||||||
transform.dx = subPixelPosition.toReal();
|
transform.dx = subPixelPosition.x.toReal();
|
||||||
transform.dy = 0;
|
transform.dy = 0;
|
||||||
transform.m11 = xform.m11();
|
transform.m11 = xform.m11();
|
||||||
transform.m12 = xform.m12();
|
transform.m12 = xform.m12();
|
||||||
@ -880,7 +883,7 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
|
QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
const QTransform &xform)
|
const QTransform &xform)
|
||||||
{
|
{
|
||||||
QImage mask = imageForGlyph(t,
|
QImage mask = imageForGlyph(t,
|
||||||
@ -936,7 +939,7 @@ QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyN
|
|||||||
}
|
}
|
||||||
|
|
||||||
glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph,
|
glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph,
|
||||||
QFixed subPixelPosition,
|
const QFixedPoint &subPixelPosition,
|
||||||
const QTransform &originalTransform,
|
const QTransform &originalTransform,
|
||||||
GlyphFormat format)
|
GlyphFormat format)
|
||||||
{
|
{
|
||||||
@ -966,7 +969,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
|
|||||||
glyphRun.glyphOffsets = &glyphOffset;
|
glyphRun.glyphOffsets = &glyphOffset;
|
||||||
|
|
||||||
DWRITE_MATRIX transform;
|
DWRITE_MATRIX transform;
|
||||||
transform.dx = subPixelPosition.toReal();
|
transform.dx = subPixelPosition.x.toReal();
|
||||||
transform.dy = 0;
|
transform.dy = 0;
|
||||||
transform.m11 = matrix.m11();
|
transform.m11 = matrix.m11();
|
||||||
transform.m12 = matrix.m12();
|
transform.m12 = matrix.m12();
|
||||||
@ -1008,7 +1011,10 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color)
|
QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t,
|
||||||
|
const QColor &color)
|
||||||
{
|
{
|
||||||
return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_ARGB), t, color);
|
return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_ARGB), t, color);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public:
|
|||||||
|
|
||||||
glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
|
glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
|
||||||
glyph_metrics_t boundingBox(glyph_t g) override;
|
glyph_metrics_t boundingBox(glyph_t g) override;
|
||||||
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed,
|
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint&,
|
||||||
const QTransform &matrix, GlyphFormat) override;
|
const QTransform &matrix, GlyphFormat) override;
|
||||||
|
|
||||||
QFixed capHeight() const override;
|
QFixed capHeight() const override;
|
||||||
@ -105,12 +105,19 @@ public:
|
|||||||
qreal maxCharWidth() const override;
|
qreal maxCharWidth() const override;
|
||||||
FaceId faceId() const override;
|
FaceId faceId() const override;
|
||||||
|
|
||||||
bool supportsSubPixelPositions() const override;
|
bool supportsHorizontalSubPixelPositions() const override;
|
||||||
|
|
||||||
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override;
|
QImage alphaMapForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition) override;
|
||||||
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
|
QImage alphaMapForGlyph(glyph_t glyph,
|
||||||
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override;
|
const QFixedPoint &subPixelPosition,
|
||||||
QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
|
const QTransform &t) override;
|
||||||
|
QImage alphaRGBMapForGlyph(glyph_t t,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &xform) override;
|
||||||
|
QImage bitmapForGlyph(glyph_t,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
const QTransform &t,
|
||||||
|
const QColor &color) override;
|
||||||
|
|
||||||
QFontEngine *cloneWithSize(qreal pixelSize) const override;
|
QFontEngine *cloneWithSize(qreal pixelSize) const override;
|
||||||
Qt::HANDLE handle() const override;
|
Qt::HANDLE handle() const override;
|
||||||
@ -126,7 +133,11 @@ public:
|
|||||||
void initializeHeightMetrics() const override;
|
void initializeHeightMetrics() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform, const QColor &color = QColor());
|
QImage imageForGlyph(glyph_t t,
|
||||||
|
const QFixedPoint &subPixelPosition,
|
||||||
|
int margin,
|
||||||
|
const QTransform &xform,
|
||||||
|
const QColor &color = QColor());
|
||||||
void collectMetrics();
|
void collectMetrics();
|
||||||
void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
|
void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
|
||||||
static QString filenameFromFontFile(IDWriteFontFile *fontFile);
|
static QString filenameFromFontFile(IDWriteFontFile *fontFile);
|
||||||
|
@ -1797,11 +1797,13 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
|
|||||||
if (recreateVertexArrays) {
|
if (recreateVertexArrays) {
|
||||||
cache->setPaintEnginePrivate(this);
|
cache->setPaintEnginePrivate(this);
|
||||||
if (!cache->populate(fe, staticTextItem->numGlyphs,
|
if (!cache->populate(fe, staticTextItem->numGlyphs,
|
||||||
staticTextItem->glyphs, staticTextItem->glyphPositions)) {
|
staticTextItem->glyphs, staticTextItem->glyphPositions,
|
||||||
|
s->renderHints)) {
|
||||||
// No space for glyphs in cache. We need to reset it and try again.
|
// No space for glyphs in cache. We need to reset it and try again.
|
||||||
cache->clear();
|
cache->clear();
|
||||||
cache->populate(fe, staticTextItem->numGlyphs,
|
cache->populate(fe, staticTextItem->numGlyphs,
|
||||||
staticTextItem->glyphs, staticTextItem->glyphPositions);
|
staticTextItem->glyphs, staticTextItem->glyphPositions,
|
||||||
|
s->renderHints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->hasPendingGlyphs()) {
|
if (cache->hasPendingGlyphs()) {
|
||||||
@ -1874,10 +1876,15 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
|
|||||||
textureCoordinates->clear();
|
textureCoordinates->clear();
|
||||||
|
|
||||||
bool supportsSubPixelPositions = fe->supportsSubPixelPositions();
|
bool supportsSubPixelPositions = fe->supportsSubPixelPositions();
|
||||||
|
bool verticalSubPixelPositions = fe->supportsVerticalSubPixelPositions()
|
||||||
|
&& (s->renderHints & QPainter::VerticalSubpixelPositioning) != 0;
|
||||||
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
|
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
|
||||||
QFixed subPixelPosition;
|
QFixedPoint subPixelPosition;
|
||||||
if (supportsSubPixelPositions)
|
if (supportsSubPixelPositions) {
|
||||||
subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
|
subPixelPosition = fe->subPixelPositionFor(staticTextItem->glyphPositions[i]);
|
||||||
|
if (!verticalSubPixelPositions)
|
||||||
|
subPixelPosition.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
|
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
|
||||||
|
|
||||||
@ -1886,7 +1893,10 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin;
|
int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin;
|
||||||
int y = qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22()) - c.baseLineY - margin;
|
int y = verticalSubPixelPositions
|
||||||
|
? qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22())
|
||||||
|
: qFloor(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22());
|
||||||
|
y -= c.baseLineY + margin;
|
||||||
|
|
||||||
vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h));
|
vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h));
|
||||||
textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
|
textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
|
||||||
|
@ -421,7 +421,9 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
|
void QOpenGLTextureGlyphCache::fillTexture(const Coord &c,
|
||||||
|
glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition)
|
||||||
{
|
{
|
||||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||||
if (ctx == nullptr) {
|
if (ctx == nullptr) {
|
||||||
|
@ -115,7 +115,9 @@ public:
|
|||||||
|
|
||||||
virtual void createTextureData(int width, int height) override;
|
virtual void createTextureData(int width, int height) override;
|
||||||
virtual void resizeTextureData(int width, int height) override;
|
virtual void resizeTextureData(int width, int height) override;
|
||||||
virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override;
|
virtual void fillTexture(const Coord &c,
|
||||||
|
glyph_t glyph,
|
||||||
|
const QFixedPoint &subPixelPosition) override;
|
||||||
virtual int glyphPadding() const override;
|
virtual int glyphPadding() const override;
|
||||||
virtual int maxTextureWidth() const override;
|
virtual int maxTextureWidth() const override;
|
||||||
virtual int maxTextureHeight() const override;
|
virtual int maxTextureHeight() const override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user