diff options
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 0d28785aa1..8dfabd48ad 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -534,69 +534,87 @@ QFontEngineFT::Glyph::~Glyph() delete [] data; } -static const uint subpixel_filter[3][3] = { - { 180, 60, 16 }, - { 38, 180, 38 }, - { 16, 60, 180 } +struct LcdFilterDummy +{ + static inline void filterPixel(uchar &, uchar &, uchar &) + {} }; -static inline uint filterPixel(uint red, uint green, uint blue, bool legacyFilter) +struct LcdFilterLegacy { - uint res; - if (legacyFilter) { - uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8; - uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8; - uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8; - res = (mid << 24) + (high << 16) + (mid << 8) + low; - } else { - uint alpha = green; - res = (alpha << 24) + (red << 16) + (green << 8) + blue; + static inline void filterPixel(uchar &red, uchar &green, uchar &blue) + { + uint r = red, g = green, b = blue; + // intra-pixel filter used by the legacy filter (adopted from _ft_lcd_filter_legacy) + red = (r * uint(65538 * 9/13) + g * uint(65538 * 1/6) + b * uint(65538 * 1/13)) / 65536; + green = (r * uint(65538 * 3/13) + g * uint(65538 * 4/6) + b * uint(65538 * 3/13)) / 65536; + blue = (r * uint(65538 * 1/13) + g * uint(65538 * 1/6) + b * uint(65538 * 9/13)) / 65536; } - return res; -} +}; -static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +template <typename LcdFilter> +static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { - int h = height; const int offs = bgr ? -1 : 1; const int w = width * 3; - while (h--) { + while (height--) { uint *dd = dst; for (int x = 0; x < w; x += 3) { - uint red = src[x+1-offs]; - uint green = src[x+1]; - uint blue = src[x+1+offs]; - *dd = filterPixel(red, green, blue, legacyFilter); - ++dd; + uchar red = src[x + 1 - offs]; + uchar green = src[x + 1]; + uchar blue = src[x + 1 + offs]; + LcdFilter::filterPixel(red, green, blue); + // alpha = green + *dd++ = (green << 24) | (red << 16) | (green << 8) | blue; } dst += width; src += src_pitch; } } -static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +{ + if (!legacyFilter) + convertRGBToARGB_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr); + else + convertRGBToARGB_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr); +} + +template <typename LcdFilter> +static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { - int h = height; const int offs = bgr ? -src_pitch : src_pitch; - while (h--) { + while (height--) { for (int x = 0; x < width; x++) { - uint red = src[x+src_pitch-offs]; - uint green = src[x+src_pitch]; - uint blue = src[x+src_pitch+offs]; - dst[x] = filterPixel(red, green, blue, legacyFilter); + uchar red = src[x + src_pitch - offs]; + uchar green = src[x + src_pitch]; + uchar blue = src[x + src_pitch + offs]; + LcdFilter::filterPixel(red, green, blue); + // alpha = green + *dst++ = (green << 24) | (red << 16) | (green << 8) | blue; } - dst += width; src += 3*src_pitch; } } -static void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch) { - for (int y = 0; y < height; ++y) { - int readpos = (y * src_pitch); - int writepos = (y * width); - for (int x = 0; x < width; ++x) { - dst[writepos + x] = (0xFF << 24) + (src[readpos + x] << 16) + (src[readpos + x] << 8) + src[readpos + x]; +static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) +{ + if (!legacyFilter) + convertRGBToARGB_V_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr); + else + convertRGBToARGB_V_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr); +} + +static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch) +{ + while (height--) { + const uchar *p = src; + const uchar * const e = p + width; + while (p < e) { + uchar gray = *p++; + *dst++ = (0xFF << 24) | (gray << 16) | (gray << 8) | gray; } + src += src_pitch; } } |