1 # HG changeset patch |
1 Description: Add a Cairo LCD filter to use FreeType LCD colour filtering features |
2 # Parent 863b8585016fffd4755445eca723011717f4b930 |
2 Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=404637 |
3 Subject: Add a Cairo LCD filter to use FreeType LCD colour filtering features |
3 Bug-Cairo: http://bugs.freedesktop.org/show_bug.cgi?id=10301 |
4 References: |
|
5 https://bugzilla.mozilla.org/show_bug.cgi?id=404637 |
|
6 http://bugs.freedesktop.org/show_bug.cgi?id=10301 |
|
7 |
4 |
8 diff --git a/config/system-headers b/config/system-headers |
5 diff --git a/config/system-headers b/config/system-headers |
9 --- a/config/system-headers |
6 --- a/config/system-headers |
10 +++ b/config/system-headers |
7 +++ b/config/system-headers |
11 @@ -262,16 +262,17 @@ Font.h |
8 @@ -267,16 +267,17 @@ Font.h |
12 Fonts.h |
9 Fonts.h |
13 fp.h |
10 fp.h |
14 fpieee.h |
11 fpieee.h |
15 frame/log.h |
12 frame/log.h |
16 frame/req.h |
13 frame/req.h |
230 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) |
227 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) |
231 |
228 |
232 /* This is the max number of FT_face objects we keep open at once |
229 /* This is the max number of FT_face objects we keep open at once |
233 */ |
230 */ |
234 #define MAX_OPEN_FACES 10 |
231 #define MAX_OPEN_FACES 10 |
235 @@ -772,46 +794,309 @@ _cairo_ft_unscaled_font_set_scale (cairo |
232 @@ -774,45 +796,309 @@ _cairo_ft_unscaled_font_set_scale (cairo |
236 unscaled->face->available_sizes[best_i].height); |
233 unscaled->face->available_sizes[best_i].height); |
237 if (error) |
234 if (error) |
238 return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
235 return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
239 } |
236 } |
240 |
237 |
547 cairo_image_surface_t **surface) |
544 cairo_image_surface_t **surface) |
548 { |
545 { |
549 int width, height, stride; |
546 int width, height, stride; |
550 unsigned char *data; |
547 unsigned char *data; |
551 int format = CAIRO_FORMAT_A8; |
548 int format = CAIRO_FORMAT_A8; |
552 - cairo_bool_t subpixel = FALSE; |
|
553 + cairo_image_surface_t *image; |
549 + cairo_image_surface_t *image; |
554 |
550 |
555 width = bitmap->width; |
551 width = bitmap->width; |
556 height = bitmap->rows; |
552 height = bitmap->rows; |
557 |
553 |
558 if (width == 0 || height == 0) { |
554 if (width == 0 || height == 0) { |
559 *surface = (cairo_image_surface_t *) |
555 *surface = (cairo_image_surface_t *) |
560 cairo_image_surface_create_for_data (NULL, format, 0, 0, 0); |
556 cairo_image_surface_create_for_data (NULL, format, 0, 0, 0); |
561 return (*surface)->base.status; |
557 return (*surface)->base.status; |
562 @@ -858,154 +1143,63 @@ _get_bitmap_surface (FT_Bitmap *bi |
558 @@ -859,150 +1145,63 @@ _get_bitmap_surface (FT_Bitmap *bi |
563 } |
559 } |
564 #endif |
560 #endif |
565 format = CAIRO_FORMAT_A1; |
561 format = CAIRO_FORMAT_A1; |
566 break; |
562 break; |
567 |
563 |
712 + if (image->base.status) { |
707 + if (image->base.status) { |
713 free (data); |
708 free (data); |
714 return (*surface)->base.status; |
709 return (*surface)->base.status; |
715 } |
710 } |
716 |
711 |
717 - if (subpixel) |
|
718 - pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE); |
|
719 - |
|
720 - _cairo_image_surface_assume_ownership_of_data ((*surface)); |
712 - _cairo_image_surface_assume_ownership_of_data ((*surface)); |
721 + if (font_options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) |
713 + if (font_options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) |
722 + pixman_image_set_component_alpha (image->pixman_image, TRUE); |
714 + pixman_image_set_component_alpha (image->pixman_image, TRUE); |
723 + |
715 + |
724 + _cairo_image_surface_assume_ownership_of_data (image); |
716 + _cairo_image_surface_assume_ownership_of_data ((image)); |
725 |
717 |
726 _cairo_debug_check_image_surface_is_defined (&(*surface)->base); |
718 _cairo_debug_check_image_surface_is_defined (&(*surface)->base); |
727 |
719 |
728 return CAIRO_STATUS_SUCCESS; |
720 return CAIRO_STATUS_SUCCESS; |
729 } |
721 } |
730 |
722 |
731 /* Converts an outline FT_GlyphSlot into an image |
723 /* Converts an outline FT_GlyphSlot into an image |
732 * |
724 * |
733 @@ -1022,129 +1216,169 @@ _get_bitmap_surface (FT_Bitmap *bi |
725 @@ -1019,129 +1218,169 @@ _get_bitmap_surface (FT_Bitmap *bi |
734 * when we add subpixel support. If so, we may want to eliminate |
726 * when we add subpixel support. If so, we may want to eliminate |
735 * this version of the code path entirely. |
727 * this version of the code path entirely. |
736 */ |
728 */ |
737 static cairo_status_t |
729 static cairo_status_t |
738 _render_glyph_outline (FT_Face face, |
730 _render_glyph_outline (FT_Face face, |
965 /* Converts a bitmap (or other) FT_GlyphSlot into an image */ |
957 /* Converts a bitmap (or other) FT_GlyphSlot into an image */ |
966 static cairo_status_t |
958 static cairo_status_t |
967 _render_glyph_bitmap (FT_Face face, |
959 _render_glyph_bitmap (FT_Face face, |
968 cairo_font_options_t *font_options, |
960 cairo_font_options_t *font_options, |
969 cairo_image_surface_t **surface) |
961 cairo_image_surface_t **surface) |
970 @@ -1354,16 +1588,17 @@ _get_pattern_ft_options (FcPattern *patt |
962 @@ -1350,16 +1589,17 @@ _get_pattern_ft_options (FcPattern *patt |
971 |
963 |
972 /* disable antialiasing if requested */ |
964 /* disable antialiasing if requested */ |
973 if (FcPatternGetBool (pattern, |
965 if (FcPatternGetBool (pattern, |
974 FC_ANTIALIAS, 0, &antialias) != FcResultMatch) |
966 FC_ANTIALIAS, 0, &antialias) != FcResultMatch) |
975 antialias = FcTrue; |
967 antialias = FcTrue; |
983 FC_HINTING, 0, &hinting) != FcResultMatch) |
975 FC_HINTING, 0, &hinting) != FcResultMatch) |
984 hinting = FcTrue; |
976 hinting = FcTrue; |
985 |
977 |
986 if (FcPatternGetInteger (pattern, |
978 if (FcPatternGetInteger (pattern, |
987 FC_RGBA, 0, &rgba) != FcResultMatch) |
979 FC_RGBA, 0, &rgba) != FcResultMatch) |
988 @@ -1389,16 +1624,35 @@ _get_pattern_ft_options (FcPattern *patt |
980 @@ -1385,16 +1625,35 @@ _get_pattern_ft_options (FcPattern *patt |
989 break; |
981 break; |
990 } |
982 } |
991 |
983 |
992 if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) { |
984 if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) { |
993 ft_options.base.subpixel_order = subpixel_order; |
985 ft_options.base.subpixel_order = subpixel_order; |
1011 + ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; |
1003 + ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; |
1012 + break; |
1004 + break; |
1013 + } |
1005 + } |
1014 + } |
1006 + } |
1015 + |
1007 + |
1016 #ifdef FC_HINT_STYLE |
1008 #ifdef FC_HINT_STYLE |
1017 if (FcPatternGetInteger (pattern, |
1009 if (FcPatternGetInteger (pattern, |
1018 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) |
1010 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) |
1019 hintstyle = FC_HINT_FULL; |
1011 hintstyle = FC_HINT_FULL; |
1020 |
1012 |
1021 if (!hinting) |
1013 if (!hinting) |
1022 hintstyle = FC_HINT_NONE; |
1014 hintstyle = FC_HINT_NONE; |
1023 |
1015 |
1024 @@ -1490,16 +1744,22 @@ _cairo_ft_options_merge (cairo_ft_option |
1016 @@ -1486,16 +1745,22 @@ _cairo_ft_options_merge (cairo_ft_option |
1025 } |
1017 } |
1026 |
1018 |
1027 if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT) |
1019 if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT) |
1028 options->base.hint_style = other->base.hint_style; |
1020 options->base.hint_style = other->base.hint_style; |
1029 |
1021 |
1042 else |
1034 else |
1043 load_target = FT_LOAD_TARGET_MONO; |
1035 load_target = FT_LOAD_TARGET_MONO; |
1044 load_flags |= FT_LOAD_MONOCHROME; |
1036 load_flags |= FT_LOAD_MONOCHROME; |
1045 } else { |
1037 } else { |
1046 switch (options->base.hint_style) { |
1038 switch (options->base.hint_style) { |
1047 @@ -1513,21 +1773,21 @@ _cairo_ft_options_merge (cairo_ft_option |
1039 @@ -1509,21 +1774,21 @@ _cairo_ft_options_merge (cairo_ft_option |
1048 break; |
1040 break; |
1049 case CAIRO_HINT_STYLE_FULL: |
1041 case CAIRO_HINT_STYLE_FULL: |
1050 case CAIRO_HINT_STYLE_DEFAULT: |
1042 case CAIRO_HINT_STYLE_DEFAULT: |
1051 if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) { |
1043 if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) { |
1052 switch (options->base.subpixel_order) { |
1044 switch (options->base.subpixel_order) { |
1114 options->hint_style != CAIRO_HINT_STYLE_NONE)) |
1106 options->hint_style != CAIRO_HINT_STYLE_NONE)) |
1115 return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
1107 return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
1116 diff --git a/gfx/cairo/cairo/src/cairo-surface.c b/gfx/cairo/cairo/src/cairo-surface.c |
1108 diff --git a/gfx/cairo/cairo/src/cairo-surface.c b/gfx/cairo/cairo/src/cairo-surface.c |
1117 --- a/gfx/cairo/cairo/src/cairo-surface.c |
1109 --- a/gfx/cairo/cairo/src/cairo-surface.c |
1118 +++ b/gfx/cairo/cairo/src/cairo-surface.c |
1110 +++ b/gfx/cairo/cairo/src/cairo-surface.c |
1119 @@ -60,16 +60,17 @@ const cairo_surface_t name = { \ |
1111 @@ -68,16 +68,17 @@ const cairo_surface_t name = { \ |
1120 0.0, /* y_fallback_resolution */ \ |
1112 NULL, /* snapshot_detach */ \ |
1121 NULL, /* clip */ \ |
1113 { 0, /* size */ \ |
1122 0, /* next_clip_serial */ \ |
1114 0, /* num_elements */ \ |
1123 0, /* current_clip_serial */ \ |
1115 0, /* element_size */ \ |
1124 FALSE, /* is_snapshot */ \ |
1116 NULL, /* elements */ \ |
1125 FALSE, /* has_font_options */ \ |
1117 }, /* snapshots */ \ |
1126 { CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \ |
1118 { CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \ |
1127 CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \ |
1119 CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \ |
1128 + CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \ |
1120 + CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \ |
1129 CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \ |
1121 CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \ |
1130 CAIRO_HINT_METRICS_DEFAULT /* hint_metrics */ \ |
1122 CAIRO_HINT_METRICS_DEFAULT /* hint_metrics */ \ |
1131 } /* font_options */ \ |
1123 } /* font_options */ \ |
1132 } |
1124 } |
1133 |
1125 |
|
1126 /* XXX error object! */ |
|
1127 |
1134 static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil); |
1128 static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil); |
1135 static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content); |
|
1136 static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format); |
|
1137 diff --git a/gfx/cairo/cairo/src/cairo-types-private.h b/gfx/cairo/cairo/src/cairo-types-private.h |
1129 diff --git a/gfx/cairo/cairo/src/cairo-types-private.h b/gfx/cairo/cairo/src/cairo-types-private.h |
1138 --- a/gfx/cairo/cairo/src/cairo-types-private.h |
1130 --- a/gfx/cairo/cairo/src/cairo-types-private.h |
1139 +++ b/gfx/cairo/cairo/src/cairo-types-private.h |
1131 +++ b/gfx/cairo/cairo/src/cairo-types-private.h |
1140 @@ -110,19 +110,45 @@ struct _cairo_array { |
1132 @@ -112,19 +112,45 @@ struct _cairo_array { |
1141 unsigned int size; |
1133 unsigned int size; |
1142 unsigned int num_elements; |
1134 unsigned int num_elements; |
1143 unsigned int element_size; |
1135 unsigned int element_size; |
1144 char **elements; |
1136 char **elements; |
1145 |
1137 |
1177 + cairo_lcd_filter_t lcd_filter; |
1169 + cairo_lcd_filter_t lcd_filter; |
1178 cairo_hint_style_t hint_style; |
1170 cairo_hint_style_t hint_style; |
1179 cairo_hint_metrics_t hint_metrics; |
1171 cairo_hint_metrics_t hint_metrics; |
1180 }; |
1172 }; |
1181 |
1173 |
1182 typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry); |
1174 /* XXX: Right now, the _cairo_color structure puts unpremultiplied |
1183 |
1175 color in the doubles and premultiplied color in the shorts. Yes, |
1184 struct _cairo_cache { |
1176 this is crazy insane, (but at least we don't export this |
1185 cairo_hash_table_t *hash_table; |
1177 madness). I'm still working on a cleaner API, but in the meantime, |
1186 diff --git a/gfx/cairo/cairo/src/cairo-xlib-screen.c b/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1178 diff --git a/gfx/cairo/cairo/src/cairo-xlib-screen.c b/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1187 --- a/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1179 --- a/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1188 +++ b/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1180 +++ b/gfx/cairo/cairo/src/cairo-xlib-screen.c |
1189 @@ -145,23 +145,32 @@ get_integer_default (Display *dpy, |
1181 @@ -56,16 +56,23 @@ |
|
1182 |
|
1183 #include "cairo-xlib-private.h" |
|
1184 #include "cairo-xlib-xrender-private.h" |
|
1185 |
|
1186 #include "cairo-xlib-surface-private.h" |
|
1187 |
|
1188 #include <fontconfig/fontconfig.h> |
|
1189 |
|
1190 +#ifndef FC_LCD_NONE |
|
1191 +#define FC_LCD_NONE 0 |
|
1192 +#define FC_LCD_DEFAULT 1 |
|
1193 +#define FC_LCD_LIGHT 2 |
|
1194 +#define FC_LCD_LEGACY 3 |
|
1195 +#endif |
|
1196 + |
|
1197 static int |
|
1198 parse_boolean (const char *v) |
|
1199 { |
|
1200 char c0, c1; |
|
1201 |
|
1202 c0 = *v; |
|
1203 if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1') |
|
1204 return 1; |
|
1205 @@ -145,23 +152,32 @@ get_integer_default (Display *dpy, |
1190 static void |
1206 static void |
1191 _cairo_xlib_init_screen_font_options (Display *dpy, |
1207 _cairo_xlib_init_screen_font_options (Display *dpy, |
1192 cairo_xlib_screen_info_t *info) |
1208 cairo_xlib_screen_t *info) |
1193 { |
1209 { |
1194 cairo_bool_t xft_hinting; |
1210 cairo_bool_t xft_hinting; |
1195 cairo_bool_t xft_antialias; |
1211 cairo_bool_t xft_antialias; |
1196 int xft_hintstyle; |
1212 int xft_hintstyle; |
1197 int xft_rgba; |
1213 int xft_rgba; |
1217 if (!get_integer_default (dpy, "hintstyle", &xft_hintstyle)) |
1233 if (!get_integer_default (dpy, "hintstyle", &xft_hintstyle)) |
1218 xft_hintstyle = FC_HINT_FULL; |
1234 xft_hintstyle = FC_HINT_FULL; |
1219 |
1235 |
1220 if (!get_integer_default (dpy, "rgba", &xft_rgba)) |
1236 if (!get_integer_default (dpy, "rgba", &xft_rgba)) |
1221 { |
1237 { |
1222 @@ -234,28 +243,47 @@ _cairo_xlib_init_screen_font_options (Di |
1238 @@ -234,28 +250,47 @@ _cairo_xlib_init_screen_font_options (Di |
1223 subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; |
1239 subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; |
1224 break; |
1240 break; |
1225 case FC_RGBA_UNKNOWN: |
1241 case FC_RGBA_UNKNOWN: |
1226 case FC_RGBA_NONE: |
1242 case FC_RGBA_NONE: |
1227 default: |
1243 default: |
1260 cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order); |
1276 cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order); |
1261 + _cairo_font_options_set_lcd_filter (&info->font_options, lcd_filter); |
1277 + _cairo_font_options_set_lcd_filter (&info->font_options, lcd_filter); |
1262 cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON); |
1278 cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON); |
1263 } |
1279 } |
1264 |
1280 |
1265 cairo_xlib_screen_info_t * |
1281 cairo_xlib_screen_t * |
1266 _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info) |
1282 _cairo_xlib_screen_reference (cairo_xlib_screen_t *info) |
1267 { |
1283 { |
1268 assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); |
1284 assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); |
1269 |
1285 |
1270 diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h |
1286 diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h |
1271 --- a/gfx/cairo/cairo/src/cairoint.h |
1287 --- a/gfx/cairo/cairo/src/cairoint.h |
1272 +++ b/gfx/cairo/cairo/src/cairoint.h |
1288 +++ b/gfx/cairo/cairo/src/cairoint.h |
1273 @@ -1444,16 +1444,23 @@ extern const cairo_private uint16_t _cai |
1289 @@ -1400,16 +1400,23 @@ extern const cairo_private uint16_t _cai |
1274 |
1290 |
1275 cairo_private void |
1291 cairo_private void |
1276 _cairo_font_options_init_default (cairo_font_options_t *options); |
1292 _cairo_font_options_init_default (cairo_font_options_t *options); |
1277 |
1293 |
1278 cairo_private void |
1294 cairo_private void |