ALT Linux Bugzilla
– Attachment 3237 Details for
Bug 18560
qt4 игнорирует настройки lcdfilter в fontconfig
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
Второй из патчей лончпадовского бага
40.ftlcdfil.diff (text/plain), 22.00 KB, created by
Alexey Morozov
on 2009-01-19 07:44:50 MSK
(
hide
)
Description:
Второй из патчей лончпадовского бага
Filename:
MIME Type:
Creator:
Alexey Morozov
Created:
2009-01-19 07:44:50 MSK
Size:
22.00 KB
patch
obsolete
>--- qt-x11-opensource-src-4.4.0/src/gui/text/qfontengine_ft.cpp 2008-07-27 22:59:35.000000000 +0800 >+++ qt-x11-opensource-src-4.4.0n/src/gui/text/qfontengine_ft.cpp 2008-07-27 23:22:12.000000000 +0800 >@@ -66,6 +66,8 @@ > #include FT_TYPE1_TABLES_H > #include FT_GLYPH_H > >+#include FT_LCD_FILTER_H >+ > QT_BEGIN_NAMESPACE > > /* >@@ -100,6 +102,296 @@ > return (HB_Error)error; > } > >+// ------------- copied from David Turner's lcd patches ----------------------- >+ >+/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot >+ * into a different format. For example, we want to convert a >+ * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit >+ * ARGB or ABGR bitmap. >+ * >+ * this function prepares a target descriptor for this operation. >+ * >+ * input :: target bitmap descriptor. The function will set its >+ * 'width', 'rows' and 'pitch' fields, and only these >+ * >+ * slot :: the glyph slot containing the source bitmap. this >+ * function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP >+ * >+ * mode :: the requested final rendering mode. supported values are >+ * MONO, NORMAL (i.e. gray), LCD and LCD_V >+ * >+ * the function returns the size in bytes of the corresponding buffer, >+ * it's up to the caller to allocate the corresponding memory block >+ * before calling _fill_xrender_bitmap >+ * >+ * it also returns -1 in case of error (e.g. incompatible arguments, >+ * like trying to convert a gray bitmap into a monochrome one) >+ */ >+static int >+_compute_xrender_bitmap_size( FT_Bitmap* target, >+ FT_GlyphSlot slot, >+ FT_Render_Mode mode ) >+{ >+ FT_Bitmap* ftbit; >+ int width, height, pitch; >+ >+ if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) >+ return -1; >+ >+ // compute the size of the final bitmap >+ ftbit = &slot->bitmap; >+ >+ width = ftbit->width; >+ height = ftbit->rows; >+ pitch = (width+3) & ~3; >+ >+ switch ( ftbit->pixel_mode ) >+ { >+ case FT_PIXEL_MODE_MONO: >+ if ( mode == FT_RENDER_MODE_MONO ) >+ { >+ pitch = (((width+31) & ~31) >> 3); >+ break; >+ } >+ /* fall-through */ >+ >+ case FT_PIXEL_MODE_GRAY: >+ if ( mode == FT_RENDER_MODE_LCD || >+ mode == FT_RENDER_MODE_LCD_V ) >+ { >+ /* each pixel is replicated into a 32-bit ARGB value */ >+ pitch = width*4; >+ } >+ break; >+ >+ case FT_PIXEL_MODE_LCD: >+ if ( mode != FT_RENDER_MODE_LCD ) >+ return -1; >+ >+ /* horz pixel triplets are packed into 32-bit ARGB values */ >+ width /= 3; >+ pitch = width*4; >+ break; >+ >+ case FT_PIXEL_MODE_LCD_V: >+ if ( mode != FT_RENDER_MODE_LCD_V ) >+ return -1; >+ >+ /* vert pixel triplets are packed into 32-bit ARGB values */ >+ height /= 3; >+ pitch = width*4; >+ break; >+ >+ default: /* unsupported source format */ >+ return -1; >+ } >+ >+ target->width = width; >+ target->rows = height; >+ target->pitch = pitch; >+ target->buffer = NULL; >+ >+ return pitch * height; >+} >+ >+/* this functions converts the glyph bitmap found in a FT_GlyphSlot >+ * into a different format (see _compute_xrender_bitmap_size) >+ * >+ * you should call this function after _compute_xrender_bitmap_size >+ * >+ * target :: target bitmap descriptor. Note that its 'buffer' pointer >+ * must point to memory allocated by the caller >+ * >+ * slot :: the glyph slot containing the source bitmap >+ * >+ * mode :: the requested final rendering mode >+ * >+ * bgr :: boolean, set if BGR or VBGR pixel ordering is needed >+ */ >+static void >+_fill_xrender_bitmap( FT_Bitmap* target, >+ FT_GlyphSlot slot, >+ FT_Render_Mode mode, >+ int bgr ) >+{ >+ FT_Bitmap* ftbit = &slot->bitmap; >+ >+ { >+ unsigned char* srcLine = ftbit->buffer; >+ unsigned char* dstLine = target->buffer; >+ int src_pitch = ftbit->pitch; >+ int width = target->width; >+ int height = target->rows; >+ int pitch = target->pitch; >+ int subpixel; >+ int h; >+ >+ subpixel = ( mode == FT_RENDER_MODE_LCD || >+ mode == FT_RENDER_MODE_LCD_V ); >+ >+ if ( src_pitch < 0 ) >+ srcLine -= src_pitch*(ftbit->rows-1); >+ >+ switch ( ftbit->pixel_mode ) >+ { >+ case FT_PIXEL_MODE_MONO: >+ if ( subpixel ) /* convert mono to ARGB32 values */ >+ { >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ { >+ int x; >+ >+ for ( x = 0; x < width; x++ ) >+ { >+ if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) ) >+ ((unsigned int*)dstLine)[x] = 0xffffffffU; >+ } >+ } >+ } >+ else if ( mode == FT_RENDER_MODE_NORMAL ) /* convert mono to 8-bit gray */ >+ { >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ { >+ int x; >+ >+ for ( x = 0; x < width; x++ ) >+ { >+ if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) ) >+ dstLine[x] = 0xff; >+ } >+ } >+ } >+ else /* copy mono to mono */ >+ { >+ int bytes = (width+7) >> 3; >+ >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ memcpy( dstLine, srcLine, bytes ); >+ } >+ break; >+ >+ case FT_PIXEL_MODE_GRAY: >+ if ( subpixel ) /* convert gray to ARGB32 values */ >+ { >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ { >+ int x; >+ unsigned int* dst = (unsigned int*)dstLine; >+ >+ for ( x = 0; x < width; x++ ) >+ { >+ unsigned int pix = srcLine[x]; >+ >+ pix |= (pix << 8); >+ pix |= (pix << 16); >+ >+ dst[x] = pix; >+ } >+ } >+ } >+ else /* copy gray into gray */ >+ { >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ memcpy( dstLine, srcLine, width ); >+ } >+ break; >+ >+ case FT_PIXEL_MODE_LCD: >+ if ( !bgr ) >+ { >+ /* convert horizontal RGB into ARGB32 */ >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ { >+ int x; >+ unsigned char* src = srcLine; >+ unsigned int* dst = (unsigned int*)dstLine; >+ >+ for ( x = 0; x < width; x++, src += 3 ) >+ { >+ unsigned int pix; >+ >+ pix = ((unsigned int)src[0] << 16) | >+ ((unsigned int)src[1] << 8) | >+ ((unsigned int)src[2] ) | >+ ((unsigned int)src[1] << 24) ; >+ >+ dst[x] = pix; >+ } >+ } >+ } >+ else >+ { >+ /* convert horizontal BGR into ARGB32 */ >+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) >+ { >+ int x; >+ unsigned char* src = srcLine; >+ unsigned int* dst = (unsigned int*)dstLine; >+ >+ for ( x = 0; x < width; x++, src += 3 ) >+ { >+ unsigned int pix; >+ >+ pix = ((unsigned int)src[2] << 16) | >+ ((unsigned int)src[1] << 8) | >+ ((unsigned int)src[0] ) | >+ ((unsigned int)src[1] << 24) ; >+ >+ dst[x] = pix; >+ } >+ } >+ } >+ break; >+ >+ default: /* FT_PIXEL_MODE_LCD_V */ >+ /* convert vertical RGB into ARGB32 */ >+ if ( !bgr ) >+ { >+ for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch ) >+ { >+ int x; >+ unsigned char* src = srcLine; >+ unsigned int* dst = (unsigned int*)dstLine; >+ >+ for ( x = 0; x < width; x++, src += 1 ) >+ { >+ unsigned int pix; >+ >+ pix = ((unsigned int)src[0] << 16) | >+ ((unsigned int)src[src_pitch] << 8) | >+ ((unsigned int)src[src_pitch*2] ) | >+ ((unsigned int)src[src_pitch] << 24) ; >+ >+ dst[x] = pix; >+ } >+ } >+ } >+ else >+ { >+ for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch ) >+ { >+ int x; >+ unsigned char* src = srcLine; >+ unsigned int* dst = (unsigned int*)dstLine; >+ >+ for ( x = 0; x < width; x++, src += 1 ) >+ { >+ unsigned int pix; >+ >+ pix = ((unsigned int)src[src_pitch*2] << 16) | >+ ((unsigned int)src[src_pitch] << 8) | >+ ((unsigned int)src[0] ) | >+ ((unsigned int)src[src_pitch] << 24) ; >+ >+ dst[x] = pix; >+ } >+ } >+ } >+ } >+ } >+} >+ >+ > // -------------------------- Freetype support ------------------------------ > > class QtFreetypeData >@@ -499,12 +791,6 @@ > delete [] data; > } > >-static const uint subpixel_filter[3][3] = { >- { 180, 60, 16 }, >- { 38, 180, 38 }, >- { 16, 60, 180 } >-}; >- > QFontEngineFT::QFontEngineFT(const QFontDef &fd) > { > fontDef = fd; >@@ -631,16 +917,17 @@ > QFontEngineFT::GlyphInfo info; > > Q_ASSERT(format != Format_None); >- bool hsubpixel = false; >- int vfactor = 1; > int load_flags = FT_LOAD_DEFAULT | default_load_flags; >+ FT_Render_Mode mode = FT_RENDER_MODE_NORMAL; > if (outline_drawing) { > load_flags = FT_LOAD_NO_BITMAP; >+ } else if (format == Format_Mono) { >+ mode = FT_RENDER_MODE_MONO; > } else if (format == Format_A32) { > if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) { >- hsubpixel = true; >+ mode = FT_RENDER_MODE_LCD; > } else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) { >- vfactor = 3; >+ mode = FT_RENDER_MODE_LCD_V; > } > > } >@@ -677,235 +964,31 @@ > > FT_GlyphSlot slot = face->glyph; > >- int left = slot->metrics.horiBearingX; >- int right = slot->metrics.horiBearingX + slot->metrics.width; >- int top = slot->metrics.horiBearingY; >- int bottom = slot->metrics.horiBearingY - slot->metrics.height; >- if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { >- int l, r, t, b; >- FT_Vector vector; >- vector.x = left; >- vector.y = top; >- FT_Vector_Transform(&vector, &matrix); >- l = r = vector.x; >- t = b = vector.y; >- vector.x = right; >- vector.y = top; >- FT_Vector_Transform(&vector, &matrix); >- if (l > vector.x) l = vector.x; >- if (r < vector.x) r = vector.x; >- if (t < vector.y) t = vector.y; >- if (b > vector.y) b = vector.y; >- vector.x = right; >- vector.y = bottom; >- FT_Vector_Transform(&vector, &matrix); >- if (l > vector.x) l = vector.x; >- if (r < vector.x) r = vector.x; >- if (t < vector.y) t = vector.y; >- if (b > vector.y) b = vector.y; >- vector.x = left; >- vector.y = bottom; >- FT_Vector_Transform(&vector, &matrix); >- if (l > vector.x) l = vector.x; >- if (r < vector.x) r = vector.x; >- if (t < vector.y) t = vector.y; >- if (b > vector.y) b = vector.y; >- left = l; >- right = r; >- top = t; >- bottom = b; >- } >- left = FLOOR(left); >- right = CEIL(right); >- bottom = FLOOR(bottom); >- top = CEIL(top); >- >- int hpixels = TRUNC(right - left); >- if (hsubpixel) >- hpixels = hpixels*3 + 8; >- info.width = hpixels; >- info.height = TRUNC(top - bottom); >- info.x = -TRUNC(left); >- info.y = TRUNC(top); >+ if (slot->format != FT_GLYPH_FORMAT_BITMAP) { >+ FT_Library library = slot->library; >+ FT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT ); >+ FT_Render_Glyph( slot, mode ); >+ FT_Library_SetLcdFilter( library, FT_LCD_FILTER_NONE ); >+ } >+ >+ FT_Bitmap bitmap; >+ int size = _compute_xrender_bitmap_size( &bitmap, slot, mode ); >+ if (size < 0) >+ return 0; >+ >+ info.width = bitmap.width; >+ info.height = bitmap.rows; >+ info.x = - slot->bitmap_left; >+ info.y = slot->bitmap_top; > info.xOff = TRUNC(ROUND(slot->advance.x)); > info.yOff = 0; >- if (hsubpixel) { >- info.width /= 3; >- info.x += 1; >- } > >- int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : >- (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); >- int size = pitch * info.height; > uchar *glyph_buffer = new uchar[size]; >- >- if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { >- FT_Bitmap bitmap; >- bitmap.rows = info.height*vfactor; >- bitmap.width = hpixels; >- bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3); >- if (!hsubpixel && vfactor == 1) >- bitmap.buffer = glyph_buffer; >- else >- bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch]; >- memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch); >- bitmap.pixel_mode = format == Format_Mono ? ft_pixel_mode_mono : ft_pixel_mode_grays; >- FT_Matrix matrix; >- matrix.xx = (hsubpixel ? 3 : 1) << 16; >- matrix.yy = vfactor << 16; >- matrix.yx = matrix.xy = 0; >- >- FT_Outline_Transform(&slot->outline, &matrix); >- FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor); >- FT_Outline_Get_Bitmap(qt_getFreetype(), &slot->outline, &bitmap); >- if (hsubpixel) { >- Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); >- Q_ASSERT(antialias); >- const uchar *src = bitmap.buffer; >- uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch]; >- uchar *c = convoluted; >- // convolute the bitmap with a triangle filter to get rid of color fringes >- // If we take account for a gamma value of 2, we end up with >- // weights of 1, 4, 9, 4, 1. We use an approximation of 1, 3, 8, 3, 1 here, >- // as this nicely sums up to 16 :) >- int h = info.height; >- while (h--) { >- c[0] = c[1] = 0; >- // >- for (int x = 2; x < bitmap.width - 2; ++x) { >- uint sum = src[x-2] + 3*src[x-1] + 8*src[x] + 3*src[x+1] + src[x+2]; >- c[x] = (uchar) (sum >> 4); >- } >- c[bitmap.width - 2] = c[bitmap.width -1] = 0; >- src += bitmap.pitch; >- c += bitmap.pitch; >- } >- >- uint *dst = (uint *)glyph_buffer; >- src = convoluted; >- h = info.height; >- if (subpixelType == QFontEngineFT::Subpixel_RGB) { >- while (h--) { >- uint *dd = dst; >- for (int x = 1; x < bitmap.width - 1; x += 3) { >- uint red = src[x]; >- uint green = src[x+1]; >- uint blue = src[x+2]; >- uint alpha = green; >- uint res = (alpha << 24) + (red << 16) + (green << 8) + blue; >- *dd = res; >- ++dd; >- } >- dst += info.width; >- src += bitmap.pitch; >- } >- } else { >- while (h--) { >- uint *dd = dst; >- for (int x = 1; x < bitmap.width - 1; x += 3) { >- uint blue = src[x]; >- uint green = src[x+1]; >- uint red = src[x+2]; >- uint alpha = green; >- uint res = (alpha << 24) + (red << 16) + (green << 8) + blue; >- *dd = res; >- ++dd; >- } >- dst += info.width; >- src += bitmap.pitch; >- } >- } >- delete [] convoluted; >- delete [] bitmap.buffer; >- } else if (vfactor != 1) { >- uchar *src = bitmap.buffer; >- size = info.width * 4 * info.height; >- uint *dst = (uint *)glyph_buffer; >- int h = info.height; >- if (subpixelType == QFontEngineFT::Subpixel_VRGB) { >- while (h--) { >- for (int x = 0; x < info.width; x++) { >- uint red = src[x]; >- uint green = src[x+bitmap.pitch]; >- uint blue = src[x+2*bitmap.pitch]; >- 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; >- uint res = (mid << 24) + (high << 16) + (mid << 8) + low; >- dst[x] = res; >- } >- dst += info.width; >- src += 3*bitmap.pitch; >- } >- } else { >- while (h--) { >- for (int x = 0; x < info.width; x++) { >- uint blue = src[x]; >- uint green = src[x+bitmap.pitch]; >- uint red = src[x+2*bitmap.pitch]; >- 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; >- uint res = (mid << 24) + (high << 16) + (mid << 8) + low; >- dst[x] = res; >- } >- dst += info.width; >- src += 3*bitmap.pitch; >- } >- } >- delete [] bitmap.buffer; >- } >- } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { >- Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); >- uchar *src = slot->bitmap.buffer; >- uchar *dst = glyph_buffer; >- int h = slot->bitmap.rows; >- if (format == Format_Mono) { >- int bytes = ((info.width + 7) & ~7) >> 3; >- while (h--) { >- memcpy (dst, src, bytes); >- dst += pitch; >- src += slot->bitmap.pitch; >- } >- } else { >- if (hsubpixel) { >- while (h--) { >- uint *dd = (uint *)dst; >- *dd++ = 0; >- for (int x = 0; x < slot->bitmap.width; x++) { >- uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); >- *dd++ = a; >- } >- *dd++ = 0; >- dst += pitch; >- src += slot->bitmap.pitch; >- } >- } else if (vfactor != 1) { >- while (h--) { >- uint *dd = (uint *)dst; >- for (int x = 0; x < slot->bitmap.width; x++) { >- uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); >- *dd++ = a; >- } >- dst += pitch; >- src += slot->bitmap.pitch; >- } >- } else { >- while (h--) { >- for (int x = 0; x < slot->bitmap.width; x++) { >- unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00); >- dst[x] = a; >- } >- dst += pitch; >- src += slot->bitmap.pitch; >- } >- } >- } >- } else { >- qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format); >- delete [] glyph_buffer; >- return 0; >- } >+ memset(glyph_buffer, 0, size); >+ bitmap.buffer = glyph_buffer; >+ _fill_xrender_bitmap(&bitmap, slot, mode, >+ (subpixelType == QFontEngineFT::Subpixel_BGR || >+ subpixelType == QFontEngineFT::Subpixel_VBGR)); > > bool large_glyph = (((signed char)(slot->linearHoriAdvance>>16) != slot->linearHoriAdvance>>16) > || ((uchar)(info.width) != info.width) >@@ -928,9 +1011,9 @@ > > g->linearAdvance = slot->linearHoriAdvance >> 10; > g->width = info.width; >- g->height = TRUNC(top - bottom); >+ g->height = info.height; > g->x = -info.x; >- g->y = TRUNC(top); >+ g->y = info.y; > g->advance = TRUNC(ROUND(slot->advance.x)); > g->format = format; > delete [] g->data;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 18560
:
3235
|
3236
| 3237 |
3238
|
3239