Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 241939 Details for
Bug 331743
x11-libs/cairo-1.9.12 + Cleartype patch
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
cleartype patch
cairo-9999-cleartype.patch (text/plain), 13.56 KB, created by
Shlomi Steinberg
on 2010-08-09 10:07:01 UTC
(
hide
)
Description:
cleartype patch
Filename:
MIME Type:
Creator:
Shlomi Steinberg
Created:
2010-08-09 10:07:01 UTC
Size:
13.56 KB
patch
obsolete
>diff -rupN cairo-9999.new/src/cairo-ft-font.c cairo-9999/src/cairo-ft-font.c >--- cairo-9999.new/src/cairo-ft-font.c 2010-08-06 21:51:21.603000022 +0300 >+++ cairo-9999/src/cairo-ft-font.c 2010-08-06 21:52:00.926000031 +0300 >@@ -57,6 +57,8 @@ > #include FT_SYNTHESIS_H > #endif > >+#define FIR_FILTER 1 >+ > #if HAVE_FT_LIBRARY_SETLCDFILTER > #include FT_LCD_FILTER_H > #endif >@@ -607,6 +609,8 @@ _cairo_ft_unscaled_font_destroy (void *a > _cairo_ft_unscaled_font_fini (unscaled); > } > >+static const int fir_filter[5] = { 0x1C, 0x38, 0x55, 0x38, 0x1C }; >+ > static cairo_bool_t > _has_unlocked_face (const void *entry) > { >@@ -1114,6 +1118,7 @@ _get_bitmap_surface (FT_Bitmap *bi > unsigned char *data; > int format = CAIRO_FORMAT_A8; > cairo_image_surface_t *image; >+ cairo_bool_t subpixel = FALSE; > > width = bitmap->width; > height = bitmap->rows; >@@ -1183,7 +1188,220 @@ _get_bitmap_surface (FT_Bitmap *bi > } > > format = CAIRO_FORMAT_A8; >- } else { >+ } else >+#ifdef FIR_FILTER >+ { >+ unsigned char* line; >+ unsigned char* bufBitmap; >+ int pitch; >+ unsigned char *data_rgba; >+ unsigned int width_rgba, stride_rgba; >+ int vmul = 1; >+ int hmul = 1; >+ >+ switch (font_options->subpixel_order) { >+ case CAIRO_SUBPIXEL_ORDER_DEFAULT: >+ case CAIRO_SUBPIXEL_ORDER_RGB: >+ case CAIRO_SUBPIXEL_ORDER_BGR: >+ default: >+ width /= 3; >+ hmul = 3; >+ break; >+ case CAIRO_SUBPIXEL_ORDER_VRGB: >+ case CAIRO_SUBPIXEL_ORDER_VBGR: >+ vmul = 3; >+ height /= 3; >+ break; >+ } >+ /* >+ * Filter the glyph to soften the color fringes >+ */ >+ width_rgba = width; >+ stride = bitmap->pitch; >+ stride_rgba = (width_rgba * 4 + 3) & ~3; >+ data_rgba = calloc (1, stride_rgba * height); >+ >+ /* perform in-place FIR filtering in either the horizontal or >+ * vertical direction. We're going to modify the RGB graymap, >+ * but that's ok, because we either own it, or its part of >+ * the FreeType glyph slot, which will not be used anymore. >+ */ >+ pitch = bitmap->pitch; >+ line = (unsigned char*)bitmap->buffer; >+ if ( pitch < 0 ) >+ line -= pitch*(height-1); >+ >+ bufBitmap = line; >+ >+ switch (font_options->subpixel_order) { >+ case CAIRO_SUBPIXEL_ORDER_DEFAULT: >+ case CAIRO_SUBPIXEL_ORDER_RGB: >+ case CAIRO_SUBPIXEL_ORDER_BGR: >+ { >+ int h; >+ >+ for ( h = height; h > 0; h--, line += pitch ) { >+ int pix[6] = { 0, 0, 0, 0, 0, 0 }; >+ unsigned char* p = line; >+ unsigned char* limit = line + width*3; >+ int nn, val, val2; >+ >+ val = p[0]; >+ for (nn = 0; nn < 3; nn++) >+ pix[2 + nn] += val * fir_filter[nn]; >+ >+ val = p[1]; >+ for (nn = 0; nn < 4; nn++) >+ pix[1 + nn] += val * fir_filter[nn]; >+ >+ p += 2; >+ >+ for ( ; p < limit; p++ ) { >+ val = p[0]; >+ for (nn = 0; nn < 5; nn++) >+ pix[nn] += val * fir_filter[nn]; >+ >+ val2 = pix[0] / 256; >+ val2 |= -(val2 >> 8); >+ p[-2] = (unsigned char)val2; >+ >+ for (nn = 0; nn < 5; nn++) >+ pix[nn] = pix[nn + 1]; >+ } >+ for (nn = 0; nn < 2; nn++ ) { >+ val2 = pix[nn] / 256; >+ val2 |= -(val2 >> 8); >+ p[nn - 2] = (unsigned char)val2; >+ } >+ } >+ } >+ break; >+ case CAIRO_SUBPIXEL_ORDER_VRGB: >+ case CAIRO_SUBPIXEL_ORDER_VBGR: >+ { >+ int w; >+ >+ for (w = 0; w < width; w++ ) { >+ int pix[6] = { 0, 0, 0, 0, 0, 0 }; >+ unsigned char* p = bufBitmap + w; >+ unsigned char* limit = bufBitmap + w + height*3*pitch; >+ int nn, val, val2; >+ >+ val = p[0]; >+ for (nn = 0; nn < 3; nn++) >+ pix[2 + nn] += val*fir_filter[nn]; >+ >+ val = p[pitch]; >+ for (nn = 0; nn < 4; nn++ ) >+ pix[1 + nn] += val * fir_filter[nn]; >+ >+ p += 2*pitch; >+ for ( ; p < limit; p += pitch ) { >+ val = p[0]; >+ for (nn = 0; nn < 5; nn++ ) >+ pix[nn] += val * fir_filter[nn]; >+ >+ val2 = pix[0] / 256; >+ val2 |= -(val2 >> 8); >+ p[-2 * pitch] = (unsigned char)val2; >+ >+ for (nn = 0; nn < 5; nn++) >+ pix[nn] = pix[nn+1]; >+ } >+ >+ for (nn = 0; nn < 2; nn++) { >+ val2 = pix[nn] / 256; >+ val2 |= -(val2 >> 8); >+ p[(nn - 2) * pitch] = (unsigned char)val2; >+ } >+ } >+ } >+ break; >+ default: /* shouldn't happen */ >+ break; >+ } >+ >+ /* now copy the resulting graymap into an ARGB32 image */ >+ { >+ unsigned char* in_line = bufBitmap; >+ unsigned char* out_line = data_rgba; >+ int h = height; >+ >+ switch (font_options->subpixel_order) { >+ case CAIRO_SUBPIXEL_ORDER_DEFAULT: >+ case CAIRO_SUBPIXEL_ORDER_RGB: >+ for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) { >+ unsigned char* in = in_line; >+ int* out = (int*)out_line; >+ int w; >+ >+ for (w = width; w > 0; w--, in += 3, out += 1) { >+ int r = in[0]; >+ int g = in[1]; >+ int b = in[2]; >+ >+ out[0] = (g << 24) | (r << 16) | (g << 8) | b; >+ } >+ } >+ break; >+ case CAIRO_SUBPIXEL_ORDER_BGR: >+ for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) { >+ unsigned char* in = in_line; >+ int* out = (int*)out_line; >+ int w; >+ >+ for (w = width; w > 0; w--, in += 3, out += 1) { >+ int r = in[2]; >+ int g = in[1]; >+ int b = in[0]; >+ >+ out[0] = (g << 24) | (r << 16) | (g << 8) | b; >+ } >+ } >+ break; >+ case CAIRO_SUBPIXEL_ORDER_VRGB: >+ for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) { >+ unsigned char* in = in_line; >+ int* out = (int*)out_line; >+ int w; >+ >+ for (w = width; w > 0; w--, in += 1, out += 1) { >+ int r = in[0]; >+ int g = in[pitch]; >+ int b = in[pitch*2]; >+ >+ out[0] = (g << 24) | (r << 16) | (g << 8) | b; >+ } >+ } >+ break; >+ case CAIRO_SUBPIXEL_ORDER_VBGR: >+ for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) { >+ unsigned char* in = in_line; >+ int* out = (int*)out_line; >+ int w; >+ >+ for (w = width; w > 0; w--, in += 1, out += 1) { >+ int r = in[2*pitch]; >+ int g = in[pitch]; >+ int b = in[0]; >+ >+ out[0] = (g << 24) | (r << 16) | (g << 8) | b; >+ } >+ } >+ break; >+ } >+ } >+ >+ if (own_buffer) >+ free (bitmap->buffer); >+ data = data_rgba; >+ stride = stride_rgba; >+ format = CAIRO_FORMAT_ARGB32; >+ subpixel = TRUE; >+ break; >+ } >+#else /* !FIR_FILTER */ >+ { > /* if we get there, the data from the source bitmap > * really comes from _fill_xrender_bitmap, and is > * made of 32-bit ARGB or ABGR values */ >@@ -1194,6 +1412,7 @@ _get_bitmap_surface (FT_Bitmap *bi > stride = bitmap->pitch; > format = CAIRO_FORMAT_ARGB32; > } >+#endif /* !FIR_FILTER */ > break; > case FT_PIXEL_MODE_GRAY2: > case FT_PIXEL_MODE_GRAY4: >@@ -1244,59 +1463,16 @@ _render_glyph_outline (FT_Face > cairo_font_options_t *font_options, > cairo_image_surface_t **surface) > { >- int rgba = FC_RGBA_UNKNOWN; >- int lcd_filter = FT_LCD_FILTER_LEGACY; >- FT_GlyphSlot glyphslot = face->glyph; >+ FT_GlyphSlot glyphslot = face->glyph; > FT_Outline *outline = &glyphslot->outline; > FT_Bitmap bitmap; > FT_BBox cbox; >- unsigned int width, height; >+ FT_Matrix matrix; >+ int hmul = 1; >+ int vmul = 1; >+ unsigned int width, height, stride; >+ cairo_bool_t subpixel = FALSE; > cairo_status_t status; >- FT_Error fterror; >- FT_Library library = glyphslot->library; >- FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL; >- >- switch (font_options->antialias) { >- case CAIRO_ANTIALIAS_NONE: >- render_mode = FT_RENDER_MODE_MONO; >- break; >- >- case CAIRO_ANTIALIAS_SUBPIXEL: >- switch (font_options->subpixel_order) { >- case CAIRO_SUBPIXEL_ORDER_DEFAULT: >- case CAIRO_SUBPIXEL_ORDER_RGB: >- case CAIRO_SUBPIXEL_ORDER_BGR: >- render_mode = FT_RENDER_MODE_LCD; >- break; >- >- case CAIRO_SUBPIXEL_ORDER_VRGB: >- case CAIRO_SUBPIXEL_ORDER_VBGR: >- render_mode = FT_RENDER_MODE_LCD_V; >- break; >- } >- >- switch (font_options->lcd_filter) { >- case CAIRO_LCD_FILTER_NONE: >- lcd_filter = FT_LCD_FILTER_NONE; >- break; >- case CAIRO_LCD_FILTER_DEFAULT: >- case CAIRO_LCD_FILTER_INTRA_PIXEL: >- lcd_filter = FT_LCD_FILTER_LEGACY; >- break; >- case CAIRO_LCD_FILTER_FIR3: >- lcd_filter = FT_LCD_FILTER_LIGHT; >- break; >- case CAIRO_LCD_FILTER_FIR5: >- lcd_filter = FT_LCD_FILTER_DEFAULT; >- break; >- } >- >- break; >- >- case CAIRO_ANTIALIAS_DEFAULT: >- case CAIRO_ANTIALIAS_GRAY: >- render_mode = FT_RENDER_MODE_NORMAL; >- } > > FT_Outline_Get_CBox (outline, &cbox); > >@@ -1307,21 +1483,20 @@ _render_glyph_outline (FT_Face > > width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6); > height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6); >+ stride = (width * hmul + 3) & ~3; > > if (width * height == 0) { > cairo_format_t format; > /* Looks like fb handles zero-sized images just fine */ >- switch (render_mode) { >- case FT_RENDER_MODE_MONO: >+ switch (font_options->antialias) { >+ case CAIRO_ANTIALIAS_NONE: > format = CAIRO_FORMAT_A1; > break; >- case FT_RENDER_MODE_LCD: >- case FT_RENDER_MODE_LCD_V: >+ case CAIRO_ANTIALIAS_SUBPIXEL: > format= CAIRO_FORMAT_ARGB32; > break; >- case FT_RENDER_MODE_LIGHT: >- case FT_RENDER_MODE_NORMAL: >- case FT_RENDER_MODE_MAX: >+ case CAIRO_ANTIALIAS_DEFAULT: >+ case CAIRO_ANTIALIAS_GRAY: > default: > format = CAIRO_FORMAT_A8; > break; >@@ -1331,75 +1506,86 @@ _render_glyph_outline (FT_Face > cairo_image_surface_create_for_data (NULL, format, 0, 0, 0); > if ((*surface)->base.status) > return (*surface)->base.status; >- } else { >+ } else { > >- int bitmap_size; >+ matrix.xx = matrix.yy = 0x10000L; >+ matrix.xy = matrix.yx = 0; > >- switch (render_mode) { >- case FT_RENDER_MODE_LCD: >- if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) { >- rgba = FC_RGBA_BGR; >- } else { >- rgba = FC_RGBA_RGB; >- } >- case FT_RENDER_MODE_LCD_V: >- if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) { >- rgba = FC_RGBA_VBGR; >- } else { >- rgba = FC_RGBA_VRGB; >- } >- break; >- case FT_RENDER_MODE_MONO: >- case FT_RENDER_MODE_LIGHT: >- case FT_RENDER_MODE_NORMAL: >- case FT_RENDER_MODE_MAX: >- default: >+ switch (font_options->antialias) { >+ case CAIRO_ANTIALIAS_NONE: >+ bitmap.pixel_mode = FT_PIXEL_MODE_MONO; >+ bitmap.num_grays = 1; >+ stride = ((width + 31) & -32) >> 3; >+ break; >+ case CAIRO_ANTIALIAS_DEFAULT: >+ case CAIRO_ANTIALIAS_GRAY: >+ bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; >+ bitmap.num_grays = 256; >+ stride = (width + 3) & -4; > break; >- } >- >-#if HAVE_FT_LIBRARY_SETLCDFILTER >- FT_Library_SetLcdFilter (library, lcd_filter); >+ case CAIRO_ANTIALIAS_SUBPIXEL: >+ switch (font_options->subpixel_order) { >+ case CAIRO_SUBPIXEL_ORDER_RGB: >+ case CAIRO_SUBPIXEL_ORDER_BGR: >+ case CAIRO_SUBPIXEL_ORDER_DEFAULT: >+ default: >+ matrix.xx *= 3; >+ hmul = 3; >+ subpixel = TRUE; >+#ifdef FIR_FILTER >+ cbox.xMin -= 64; >+ cbox.xMax += 64; >+ width += 2; > #endif >- >- fterror = FT_Render_Glyph (face->glyph, render_mode); >- >-#if HAVE_FT_LIBRARY_SETLCDFILTER >- FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE); >+ break; >+ case CAIRO_SUBPIXEL_ORDER_VRGB: >+ case CAIRO_SUBPIXEL_ORDER_VBGR: >+ matrix.yy *= 3; >+ vmul = 3; >+ subpixel = TRUE; >+#ifdef FIR_FILTER >+ cbox.yMin -= 64; >+ cbox.yMax += 64; >+ height += 2; > #endif >+ break; >+ } >+ FT_Outline_Transform (outline, &matrix); > >- if (fterror != 0) >- return _cairo_error (CAIRO_STATUS_NO_MEMORY); >+ bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; >+ bitmap.num_grays = 256; >+ stride = (width * hmul + 3) & -4; >+ } > >- bitmap_size = _compute_xrender_bitmap_size (&bitmap, >- face->glyph, >- render_mode); >- if (bitmap_size < 0) >+ bitmap.pitch = stride; >+ bitmap.width = width * hmul; >+ bitmap.rows = height * vmul; >+ bitmap.buffer = calloc (stride, bitmap.rows); >+ if (bitmap.buffer == NULL) > return _cairo_error (CAIRO_STATUS_NO_MEMORY); > >- bitmap.buffer = calloc (1, bitmap_size); >- if (bitmap.buffer == NULL) >- return _cairo_error (CAIRO_STATUS_NO_MEMORY); >+ FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul); > >- _fill_xrender_bitmap (&bitmap, face->glyph, render_mode, >- (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR)); >+ if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { >+ free (bitmap.buffer); >+ return _cairo_error (CAIRO_STATUS_NO_MEMORY); >+ } > >- /* Note: >- * _get_bitmap_surface will free bitmap.buffer if there is an error >- */ > status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface); >- if (unlikely (status)) >+ if (status) > return status; >- >- /* Note: the font's coordinate system is upside down from ours, so the >- * Y coordinate of the control box needs to be negated. Moreover, device >- * offsets are position of glyph origin relative to top left while xMin >- * and yMax are offsets of top left relative to origin. Another negation. >- */ >- cairo_surface_set_device_offset (&(*surface)->base, >- (double)-glyphslot->bitmap_left, >- (double)+glyphslot->bitmap_top); > } > >+ /* >+ * Note: the font's coordinate system is upside down from ours, so the >+ * Y coordinate of the control box needs to be negated. Moreover, device >+ * offsets are position of glyph origin relative to top left while xMin >+ * and yMax are offsets of top left relative to origin. Another negation. >+ */ >+ cairo_surface_set_device_offset (&(*surface)->base, >+ floor (-(double) cbox.xMin / 64.0), >+ floor (+(double) cbox.yMax / 64.0)); >+ > return CAIRO_STATUS_SUCCESS; > } >
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 331743
:
241937
| 241939