api: Extend cairo_antialias_t to include performace/quality hints

The existing API only described the method to be used for performing
rasterisation and unlike other API provided no opportunity for the user
to give a hint as to how to trade off performance against speed. So in
order to no be overly prescriptive, we extend the NONE/GRAY/SUBPIXEL
methods with FAST/GOOD/BEST hints and leave the backend to decide how
best to achieve those goals.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-08-30 14:24:12 +01:00
parent 6b1daace57
commit 70cd3b473d
15 changed files with 79 additions and 24 deletions

View file

@ -1266,6 +1266,7 @@ _render_glyph_outline (FT_Face face,
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_BEST:
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
@ -1299,6 +1300,8 @@ _render_glyph_outline (FT_Face face,
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_GOOD:
case CAIRO_ANTIALIAS_FAST:
render_mode = FT_RENDER_MODE_NORMAL;
}

View file

@ -678,6 +678,7 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
switch (font->base.options.antialias) {
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_BEST:
CGContextSetShouldAntialias (cgContext, TRUE);
CGContextSetShouldSmoothFonts (cgContext, TRUE);
if (CGContextSetAllowsFontSmoothingPtr &&
@ -688,6 +689,8 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
CGContextSetShouldAntialias (cgContext, FALSE);
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_GOOD:
case CAIRO_ANTIALIAS_FAST:
CGContextSetShouldAntialias (cgContext, TRUE);
CGContextSetShouldSmoothFonts (cgContext, FALSE);
break;

View file

@ -362,7 +362,10 @@ _antialias_to_string (cairo_antialias_t antialias)
"ANTIALIAS_DEFAULT", /* CAIRO_ANTIALIAS_DEFAULT */
"ANTIALIAS_NONE", /* CAIRO_ANTIALIAS_NONE */
"ANTIALIAS_GRAY", /* CAIRO_ANTIALIAS_GRAY */
"ANTIALIAS_SUBPIXEL" /* CAIRO_ANTIALIAS_SUBPIXEL */
"ANTIALIAS_SUBPIXEL", /* CAIRO_ANTIALIAS_SUBPIXEL */
"ANTIALIAS_FAST", /* CAIRO_ANTIALIAS_FAST */
"ANTIALIAS_GOOD", /* CAIRO_ANTIALIAS_GOOD */
"ANTIALIAS_BEST" /* CAIRO_ANTIALIAS_BEST */
};
assert (antialias < ARRAY_LENGTH (names));
return names[antialias];

View file

@ -50,7 +50,7 @@ struct stat {
#define NUM_OPERATORS (CAIRO_OPERATOR_HSL_LUMINOSITY+1)
#define NUM_CAPS (CAIRO_LINE_CAP_SQUARE+1)
#define NUM_JOINS (CAIRO_LINE_JOIN_BEVEL+1)
#define NUM_ANTIALIAS (CAIRO_ANTIALIAS_SUBPIXEL+1)
#define NUM_ANTIALIAS (CAIRO_ANTIALIAS_BEST+1)
#define NUM_FILL_RULE (CAIRO_FILL_RULE_EVEN_ODD+1)
struct extents {

View file

@ -1533,7 +1533,10 @@ static const char *antialias_names[] = {
"default",
"none",
"gray",
"subpixel"
"subpixel",
"fast",
"good",
"best"
};
static void
print_antialias (cairo_output_stream_t *stream, unsigned int *array)

View file

@ -229,8 +229,11 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
switch (scaled_font->base.options.antialias) {
default:
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_FAST:
case CAIRO_ANTIALIAS_GOOD:
case CAIRO_ANTIALIAS_GRAY: format = CAIRO_FORMAT_A8; break;
case CAIRO_ANTIALIAS_NONE: format = CAIRO_FORMAT_A1; break;
case CAIRO_ANTIALIAS_BEST:
case CAIRO_ANTIALIAS_SUBPIXEL: format = CAIRO_FORMAT_ARGB32; break;
}
surface = cairo_image_surface_create (format, width, height);

View file

@ -658,9 +658,12 @@ _vg_rendering_quality_from_cairo (cairo_antialias_t aa)
switch (aa) {
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_GOOD:
case CAIRO_ANTIALIAS_BEST:
return VG_RENDERING_QUALITY_BETTER;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_FAST:
return VG_RENDERING_QUALITY_FASTER;
case CAIRO_ANTIALIAS_NONE:
@ -1334,7 +1337,7 @@ _vg_surface_show_glyphs (void *abstract_surface,
op, source, &path,
CAIRO_FILL_RULE_WINDING,
CAIRO_GSTATE_TOLERANCE_DEFAULT,
CAIRO_ANTIALIAS_SUBPIXEL,
CAIRO_ANTIALIAS_DEFAULT,
clip);
BAIL:
_cairo_path_fixed_fini (&path);

View file

@ -342,9 +342,12 @@ _win32_scaled_font_create (LOGFONTW *logfont,
f->quality = NONANTIALIASED_QUALITY;
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_FAST:
case CAIRO_ANTIALIAS_GOOD:
f->quality = ANTIALIASED_QUALITY;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_BEST:
if (_have_cleartype_quality ())
f->quality = CLEARTYPE_QUALITY;
else

View file

@ -279,9 +279,12 @@ _cairo_xcb_surface_set_precision (cairo_xcb_surface_t *surface,
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
case CAIRO_ANTIALIAS_FAST:
case CAIRO_ANTIALIAS_GOOD:
precision = XCB_RENDER_POLY_MODE_IMPRECISE;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_BEST:
precision = XCB_RENDER_POLY_MODE_PRECISE;
break;
}

View file

@ -1097,8 +1097,11 @@ _cairo_xlib_surface_set_precision (cairo_xlib_display_t *display,
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
case CAIRO_ANTIALIAS_FAST:
case CAIRO_ANTIALIAS_GOOD:
precision = PolyModeImprecise;
break;
case CAIRO_ANTIALIAS_BEST:
case CAIRO_ANTIALIAS_SUBPIXEL:
precision = PolyModePrecise;
break;
@ -2966,21 +2969,9 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
goto BAIL;
}
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
pict_format =
_cairo_xlib_display_get_xrender_format (display,
CAIRO_FORMAT_A1);
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_DEFAULT:
default:
pict_format =
_cairo_xlib_display_get_xrender_format (display,
CAIRO_FORMAT_A8);
break;
}
pict_format =
_cairo_xlib_display_get_xrender_format (display,
antialias == CAIRO_ANTIALIAS_NONE ? CAIRO_FORMAT_A1 : CAIRO_FORMAT_A8);
status = _cairo_xlib_surface_set_clip_region (dst, clip_region);
if (unlikely (status))

View file

@ -158,10 +158,13 @@ static const char *
_antialias_to_string (cairo_antialias_t antialias)
{
static const char *names[] = {
"ANTIALIAS_DEFAULT", /* CAIRO_ANTIALIAS_DEFAULT */
"ANTIALIAS_NONE", /* CAIRO_ANTIALIAS_NONE */
"ANTIALIAS_GRAY", /* CAIRO_ANTIALIAS_GRAY */
"ANTIALIAS_SUBPIXEL" /* CAIRO_ANTIALIAS_SUBPIXEL */
"DEFAULT", /* CAIRO_ANTIALIAS_DEFAULT */
"NONE", /* CAIRO_ANTIALIAS_NONE */
"GRAY", /* CAIRO_ANTIALIAS_GRAY */
"SUBPIXEL", /* CAIRO_ANTIALIAS_SUBPIXEL */
"FAST", /* CAIRO_ANTIALIAS_FAST */
"GOOD", /* CAIRO_ANTIALIAS_GOOD */
"BEST", /* CAIRO_ANTIALIAS_BEST */
};
assert (antialias < ARRAY_LENGTH (names));
return names[antialias];

View file

@ -644,12 +644,35 @@ cairo_set_tolerance (cairo_t *cr, double tolerance);
* such as LCD panels
*
* Specifies the type of antialiasing to do when rendering text or shapes.
*
* As it is not necessarily clear from the above what advantages a particular
* antialias method provides, since 1.12, there is also a set of hints:
* @CAIRO_ANTIALIAS_FAST: Allow the backend to degrade raster quality for speed
* @CAIRO_ANTIALIAS_GOOD: A balance between speed and quality
* @CAIRO_ANTIALIAS_BEST: A high-fidelity, but potentially slow, raster mode
*
* These make no guarantee on how the backend will perform its rasterisation
* (if it even rasterises!), nor that they have any differing effect other
* than to enable some form of antialiasing. In the case of glyph rendering,
* @CAIRO_ANTIALIAS_FAST and @CAIRO_ANTIALIAS_GOOD will be mapped to
* @CAIRO_ANTIALIAS_GRAY, with @CAIRO_ANTALIAS_BEST being equivalent to
* @CAIRO_ANTIALIAS_SUBPIXEL.
*
* The interpretation of @CAIRO_ANTIALIAS_DEFAULT is left entirely up to
* the backend, typically this will be similar to @CAIRO_ANTIALIAS_GOOD.
**/
typedef enum _cairo_antialias {
CAIRO_ANTIALIAS_DEFAULT,
/* method */
CAIRO_ANTIALIAS_NONE,
CAIRO_ANTIALIAS_GRAY,
CAIRO_ANTIALIAS_SUBPIXEL
CAIRO_ANTIALIAS_SUBPIXEL,
/* hints */
CAIRO_ANTIALIAS_FAST,
CAIRO_ANTIALIAS_GOOD,
CAIRO_ANTIALIAS_BEST
} cairo_antialias_t;
cairo_public void

View file

@ -129,9 +129,15 @@ cairo_gobject_antialias_get_type (void)
if (g_once_init_enter (&type_volatile)) {
static const GEnumValue values[] = {
{ CAIRO_ANTIALIAS_DEFAULT, "CAIRO_ANTIALIAS_DEFAULT", "default" },
{ CAIRO_ANTIALIAS_NONE, "CAIRO_ANTIALIAS_NONE", "none" },
{ CAIRO_ANTIALIAS_GRAY, "CAIRO_ANTIALIAS_GRAY", "gray" },
{ CAIRO_ANTIALIAS_SUBPIXEL, "CAIRO_ANTIALIAS_SUBPIXEL", "subpixel" },
{ CAIRO_ANTIALIAS_FAST, "CAIRO_ANTIALIAS_FAST", "fast" },
{ CAIRO_ANTIALIAS_GOOD, "CAIRO_ANTIALIAS_GOOD", "good" },
{ CAIRO_ANTIALIAS_BEST, "CAIRO_ANTIALIAS_BEST", "best" },
{ 0, NULL, NULL }
};
GType type = g_enum_register_static (g_intern_static_string ("cairo_antialias_t"), values);

View file

@ -6597,6 +6597,9 @@ _integer_constants[] = {
{ "ANTIALIAS_NONE", CAIRO_ANTIALIAS_NONE },
{ "ANTIALIAS_GRAY", CAIRO_ANTIALIAS_GRAY },
{ "ANTIALIAS_SUBPIXEL", CAIRO_ANTIALIAS_SUBPIXEL },
{ "ANTIALIAS_FAST", CAIRO_ANTIALIAS_FAST },
{ "ANTIALIAS_GOOD", CAIRO_ANTIALIAS_GOOD },
{ "ANTIALIAS_BEST", CAIRO_ANTIALIAS_BEST },
{ "LINE_CAP_BUTT", CAIRO_LINE_CAP_BUTT },
{ "LINE_CAP_ROUND", CAIRO_LINE_CAP_ROUND },

View file

@ -2271,9 +2271,14 @@ _antialias_to_string (cairo_antialias_t antialias)
#define f(name) case CAIRO_ANTIALIAS_ ## name: return "ANTIALIAS_" #name
switch (antialias) {
f(DEFAULT);
f(NONE);
f(GRAY);
f(SUBPIXEL);
f(FAST);
f(GOOD);
f(BEST);
};
#undef f
return "UNKNOWN_ANTIALIAS";