Enable patent-free LCD rendering with FreeType 2.8.1
Use the FreeType LCD rendering path with 2.8.1 even when it has lcd- filtering disabled. This gives us proper subpixel rendering even with a freetype build with the patented lcd-filtering code disabled. The code is also simplified by removing the long pointless ifdefs for 10+ year old versions of freetype. Change-Id: I487e465317cb984b6e33c7bcc497f27cf29f9bcd Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
467cede61e
commit
f0096a2bd3
@ -66,11 +66,7 @@
|
|||||||
#include FT_TYPE1_TABLES_H
|
#include FT_TYPE1_TABLES_H
|
||||||
#include FT_GLYPH_H
|
#include FT_GLYPH_H
|
||||||
#include FT_MODULE_H
|
#include FT_MODULE_H
|
||||||
|
|
||||||
#if defined(FT_LCD_FILTER_H)
|
|
||||||
#include FT_LCD_FILTER_H
|
#include FT_LCD_FILTER_H
|
||||||
#define QT_USE_FREETYPE_LCDFILTER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FT_CONFIG_OPTIONS_H)
|
#if defined(FT_CONFIG_OPTIONS_H)
|
||||||
#include FT_CONFIG_OPTIONS_H
|
#include FT_CONFIG_OPTIONS_H
|
||||||
@ -125,12 +121,13 @@ class QtFreetypeData
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QtFreetypeData()
|
QtFreetypeData()
|
||||||
: library(0)
|
: library(0), hasPatentFreeLcdRendering(false)
|
||||||
{ }
|
{ }
|
||||||
~QtFreetypeData();
|
~QtFreetypeData();
|
||||||
|
|
||||||
FT_Library library;
|
FT_Library library;
|
||||||
QHash<QFontEngine::FaceId, QFreetypeFace *> faces;
|
QHash<QFontEngine::FaceId, QFreetypeFace *> faces;
|
||||||
|
bool hasPatentFreeLcdRendering;
|
||||||
};
|
};
|
||||||
|
|
||||||
QtFreetypeData::~QtFreetypeData()
|
QtFreetypeData::~QtFreetypeData()
|
||||||
@ -164,6 +161,11 @@ QtFreetypeData *qt_getFreetypeData()
|
|||||||
FT_Bool no_darkening = false;
|
FT_Bool no_darkening = false;
|
||||||
FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening);
|
FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening);
|
||||||
#endif
|
#endif
|
||||||
|
// FreeType has since 2.8.1 a patent free alternative to LCD-filtering.
|
||||||
|
FT_Int amajor, aminor = 0, apatch = 0;
|
||||||
|
FT_Library_Version(freetypeData->library, &amajor, &aminor, &apatch);
|
||||||
|
if (QT_VERSION_CHECK(amajor, aminor, apatch) >= QT_VERSION_CHECK(2, 8, 1))
|
||||||
|
freetypeData->hasPatentFreeLcdRendering = true;
|
||||||
}
|
}
|
||||||
return freetypeData;
|
return freetypeData;
|
||||||
}
|
}
|
||||||
@ -775,10 +777,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
|
|||||||
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||||
default_hint_style = ftInitialDefaultHintStyle;
|
default_hint_style = ftInitialDefaultHintStyle;
|
||||||
subpixelType = Subpixel_None;
|
subpixelType = Subpixel_None;
|
||||||
lcdFilterType = 0;
|
|
||||||
#if defined(FT_LCD_FILTER_H)
|
|
||||||
lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
|
lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
|
||||||
#endif
|
|
||||||
defaultFormat = Format_None;
|
defaultFormat = Format_None;
|
||||||
embeddedbitmap = false;
|
embeddedbitmap = false;
|
||||||
const QByteArray env = qgetenv("QT_NO_FT_CACHE");
|
const QByteArray env = qgetenv("QT_NO_FT_CACHE");
|
||||||
@ -1165,14 +1164,14 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
|||||||
|
|
||||||
int glyph_buffer_size = 0;
|
int glyph_buffer_size = 0;
|
||||||
QScopedArrayPointer<uchar> glyph_buffer;
|
QScopedArrayPointer<uchar> glyph_buffer;
|
||||||
#if defined(QT_USE_FREETYPE_LCDFILTER)
|
|
||||||
bool useFreetypeRenderGlyph = false;
|
bool useFreetypeRenderGlyph = false;
|
||||||
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
|
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
|
||||||
err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
|
err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
|
||||||
if (err == FT_Err_Ok)
|
// We use FT_Render_Glyph if freetype has support for lcd-filtering
|
||||||
|
// or is version 2.8.1 or higher and can do without.
|
||||||
|
if (err == FT_Err_Ok || qt_getFreetypeData()->hasPatentFreeLcdRendering)
|
||||||
useFreetypeRenderGlyph = true;
|
useFreetypeRenderGlyph = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useFreetypeRenderGlyph) {
|
if (useFreetypeRenderGlyph) {
|
||||||
err = FT_Render_Glyph(slot, hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V);
|
err = FT_Render_Glyph(slot, hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V);
|
||||||
|
|
||||||
@ -1193,9 +1192,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
|||||||
convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
|
convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
|
||||||
else if (vfactor != 1)
|
else if (vfactor != 1)
|
||||||
convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
|
convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
|
||||||
} else
|
} else {
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int left = slot->metrics.horiBearingX;
|
int left = slot->metrics.horiBearingX;
|
||||||
int right = slot->metrics.horiBearingX + slot->metrics.width;
|
int right = slot->metrics.horiBearingX + slot->metrics.width;
|
||||||
int top = slot->metrics.horiBearingY;
|
int top = slot->metrics.horiBearingY;
|
||||||
@ -1262,9 +1259,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
|||||||
Q_ASSERT(antialias);
|
Q_ASSERT(antialias);
|
||||||
uchar *convoluted = new uchar[bitmap_buffer_size];
|
uchar *convoluted = new uchar[bitmap_buffer_size];
|
||||||
bool useLegacyLcdFilter = false;
|
bool useLegacyLcdFilter = false;
|
||||||
#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
|
|
||||||
useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
|
useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
|
||||||
#endif
|
|
||||||
uchar *buffer = bitmap.buffer;
|
uchar *buffer = bitmap.buffer;
|
||||||
if (!useLegacyLcdFilter) {
|
if (!useLegacyLcdFilter) {
|
||||||
convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
|
convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
|
||||||
|
Loading…
Reference in New Issue
Block a user