Implement aliased text rendering with DirectWrite
This creates aliased glyphs using the DirectWrite engine when requested. Note: There was previously a fallback to GDI to support aliased text, which ignored the hinting settings. This patch also removes that fallback. [ChangeLog][Windows] Support QFont::NoAntialias with the DirectWrite font engine. Pick-to: 6.6 6.5 Fixes: QTBUG-97645 Change-Id: I587f56ace468cfdd57debe7bc8492a96587a4e05 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit 421e7621faa50bf9007076d6be4e0da9514edc59)
This commit is contained in:
parent
a225fb5d89
commit
b62b6094dd
@ -162,8 +162,11 @@ static DWRITE_MEASURING_MODE renderModeToMeasureMode(DWRITE_RENDERING_MODE rende
|
||||
}
|
||||
}
|
||||
|
||||
static DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(const QFontDef &fontDef)
|
||||
DWRITE_RENDERING_MODE QWindowsFontEngineDirectWrite::hintingPreferenceToRenderingMode(const QFontDef &fontDef) const
|
||||
{
|
||||
if ((fontDef.styleStrategy & QFont::NoAntialias) && glyphFormat != QFontEngine::Format_ARGB)
|
||||
return DWRITE_RENDERING_MODE_ALIASED;
|
||||
|
||||
QFont::HintingPreference hintingPreference = QFont::HintingPreference(fontDef.hintingPreference);
|
||||
if (!qFuzzyCompare(qApp->devicePixelRatio(), 1.0) && hintingPreference == QFont::PreferDefaultHinting) {
|
||||
// Microsoft documentation recommends using asymmetric rendering for small fonts
|
||||
@ -484,7 +487,8 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
|
||||
DWRITE_RENDERING_MODE renderMode = hintingPreferenceToRenderingMode(fontDef);
|
||||
bool needsDesignMetrics = shaperFlags & QFontEngine::DesignMetrics;
|
||||
if (!needsDesignMetrics && (renderMode == DWRITE_RENDERING_MODE_GDI_CLASSIC
|
||||
|| renderMode == DWRITE_RENDERING_MODE_GDI_NATURAL)) {
|
||||
|| renderMode == DWRITE_RENDERING_MODE_GDI_NATURAL
|
||||
|| renderMode == DWRITE_RENDERING_MODE_ALIASED)) {
|
||||
hr = m_directWriteFontFace->GetGdiCompatibleGlyphMetrics(float(fontDef.pixelSize),
|
||||
1.0f,
|
||||
NULL,
|
||||
@ -673,7 +677,8 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph,
|
||||
|
||||
bool QWindowsFontEngineDirectWrite::supportsHorizontalSubPixelPositions() const
|
||||
{
|
||||
return true;
|
||||
DWRITE_RENDERING_MODE renderMode = hintingPreferenceToRenderingMode(fontDef);
|
||||
return renderMode != DWRITE_RENDERING_MODE_ALIASED;
|
||||
}
|
||||
|
||||
QFontEngine::Properties QWindowsFontEngineDirectWrite::properties() const
|
||||
@ -776,7 +781,10 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
RECT rect;
|
||||
glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
|
||||
glyphAnalysis->GetAlphaTextureBounds(renderMode == DWRITE_RENDERING_MODE_ALIASED
|
||||
? DWRITE_TEXTURE_ALIASED_1x1
|
||||
: DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
&rect);
|
||||
|
||||
if (rect.top == rect.bottom || rect.left == rect.right)
|
||||
return QImage();
|
||||
@ -857,7 +865,8 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||
b,
|
||||
a,
|
||||
colorGlyphsAnalysis,
|
||||
boundingRect);
|
||||
boundingRect,
|
||||
renderMode);
|
||||
}
|
||||
colorGlyphsAnalysis->Release();
|
||||
|
||||
@ -884,7 +893,8 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||
b,
|
||||
a,
|
||||
glyphAnalysis,
|
||||
boundingRect);
|
||||
boundingRect,
|
||||
renderMode);
|
||||
}
|
||||
|
||||
glyphAnalysis->Release();
|
||||
@ -902,7 +912,8 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination,
|
||||
float b,
|
||||
float a,
|
||||
IDWriteGlyphRunAnalysis *glyphAnalysis,
|
||||
const QRect &boundingRect)
|
||||
const QRect &boundingRect,
|
||||
DWRITE_RENDERING_MODE renderMode)
|
||||
{
|
||||
const int width = destination->width();
|
||||
const int height = destination->height();
|
||||
@ -923,12 +934,14 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination,
|
||||
BYTE *alphaValues = alphaValueArray.data();
|
||||
memset(alphaValues, 0, size);
|
||||
|
||||
HRESULT hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
HRESULT hr = glyphAnalysis->CreateAlphaTexture(renderMode == DWRITE_RENDERING_MODE_ALIASED
|
||||
? DWRITE_TEXTURE_ALIASED_1x1
|
||||
: DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
&rect,
|
||||
alphaValues,
|
||||
size);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (destination->hasAlphaChannel()) {
|
||||
if (destination->hasAlphaChannel()) { // Color glyphs
|
||||
for (int y = 0; y < height; ++y) {
|
||||
uint *dest = reinterpret_cast<uint *>(destination->scanLine(y));
|
||||
BYTE *src = alphaValues + width * 3 * y;
|
||||
@ -946,7 +959,16 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination,
|
||||
qRound(qAlpha(currentRgb) * (1.0 - averageAlpha) + averageAlpha * 255));
|
||||
}
|
||||
}
|
||||
} else if (renderMode == DWRITE_RENDERING_MODE_ALIASED) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
uint *dest = reinterpret_cast<uint *>(destination->scanLine(y));
|
||||
BYTE *src = alphaValues + width * y;
|
||||
|
||||
for (int x = 0; x < width; ++x) {
|
||||
int alpha = *(src++);
|
||||
dest[x] = (alpha << 16) + (alpha << 8) + alpha;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
uint *dest = reinterpret_cast<uint *>(destination->scanLine(y));
|
||||
@ -1121,7 +1143,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
RECT rect;
|
||||
glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
|
||||
glyphAnalysis->GetAlphaTextureBounds(renderMode == DWRITE_RENDERING_MODE_ALIASED ? DWRITE_TEXTURE_ALIASED_1x1 : DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
|
||||
glyphAnalysis->Release();
|
||||
|
||||
int margin = glyphMargin(format);
|
||||
|
@ -22,6 +22,7 @@ QT_REQUIRE_CONFIG(directwrite);
|
||||
|
||||
#include <QtGui/private/qfontengine_p.h>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <dwrite.h>
|
||||
|
||||
struct IDWriteFont;
|
||||
struct IDWriteFontFace;
|
||||
@ -108,8 +109,16 @@ private:
|
||||
const QTransform &xform,
|
||||
const QColor &color = QColor());
|
||||
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,
|
||||
DWRITE_RENDERING_MODE renderMode);
|
||||
static QString filenameFromFontFile(IDWriteFontFile *fontFile);
|
||||
DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(const QFontDef &fontDef) const;
|
||||
|
||||
const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user