diff --git a/gfx/cairo/README b/gfx/cairo/README index 9649f763902..81ab5549b75 100644 --- a/gfx/cairo/README +++ b/gfx/cairo/README @@ -7,8 +7,8 @@ http://www.cairographics.org/. VERSIONS: - cairo (1.6.x - 1.5.16-23-gbb76eb5) - pixman (0.10.x - pixman-0.10.0-5-g4cde088) + cairo (1.6.x - 1.5.18-3-g3d22902) + pixman (0.10.x - pixman-0.10.0-8-g0b207ae) glitz 0.5.2 (cvs - 2006-01-10) ***** NOTE FOR VISUAL C++ 6.0 ***** diff --git a/gfx/cairo/cairo/src/cairo-cff-subset.c b/gfx/cairo/cairo/src/cairo-cff-subset.c index a3dc527b056..53c5a175dff 100644 --- a/gfx/cairo/cairo/src/cairo-cff-subset.c +++ b/gfx/cairo/cairo/src/cairo-cff-subset.c @@ -34,6 +34,11 @@ * Eugeniy Meshcheryakov */ +/* + * Useful links: + * http://www.adobe.com/devnet/font/pdfs/5176.CFF.pdf + */ + #define _BSD_SOURCE /* for snprintf(), strdup() */ #include "cairoint.h" #include "cairo-scaled-font-subsets-private.h" diff --git a/gfx/cairo/cairo/src/cairo-pattern.c b/gfx/cairo/cairo/src/cairo-pattern.c index bd67163de7d..097fc394c4d 100644 --- a/gfx/cairo/cairo/src/cairo-pattern.c +++ b/gfx/cairo/cairo/src/cairo-pattern.c @@ -1084,6 +1084,9 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern) * Sets the mode to be used for drawing outside the area of a pattern. * See #cairo_extend_t for details on the semantics of each extend * strategy. + * + * The default extend mode is %CAIRO_EXTEND_NONE for surface patterns + * and %CAIRO_EXTEND_PAD for gradient patterns. **/ void cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend) @@ -1980,50 +1983,65 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern, (cairo_surface_pattern_t *) pattern; cairo_surface_t *surface = surface_pattern->surface; cairo_matrix_t imatrix; - double x, y; - /* Initialize to keep the compiler quiet. */ - int left=0, right=0, top=0, bottom=0; - int lx, rx, ty, by; - int sx, sy; - cairo_bool_t set = FALSE; + double x1, y1, x2, y2; status = _cairo_surface_get_extents (surface, &surface_extents); if (status) return status; + x1 = surface_extents.x; + y1 = surface_extents.y; + x2 = x1 + surface_extents.width; + y2 = y1 + surface_extents.height; + + /* The filter can effectively enlarge the extents of the + * pattern, so extend as necessary. Note: We aren't doing any + * backend-specific querying of filter box sizes at this time, + * (since currently no specific backends that could do custom + * filters are calling _cairo_pattern_get_extents). */ + switch (pattern->filter) { + case CAIRO_FILTER_GOOD: + case CAIRO_FILTER_BEST: + case CAIRO_FILTER_BILINEAR: + x1 -= 0.5; + y1 -= 0.5; + x2 += 0.5; + y2 += 0.5; + break; + case CAIRO_FILTER_FAST: + case CAIRO_FILTER_NEAREST: + case CAIRO_FILTER_GAUSSIAN: + default: + /* Nothing to do */ + break; + } + imatrix = pattern->matrix; status = cairo_matrix_invert (&imatrix); /* cairo_pattern_set_matrix ensures the matrix is invertible */ assert (status == CAIRO_STATUS_SUCCESS); - /* XXX Use _cairo_matrix_transform_bounding_box here */ - for (sy = 0; sy <= 1; sy++) { - for (sx = 0; sx <= 1; sx++) { - x = surface_extents.x + sx * surface_extents.width; - y = surface_extents.y + sy * surface_extents.height; - cairo_matrix_transform_point (&imatrix, &x, &y); - if (x < 0) x = 0; - if (x > CAIRO_RECT_INT_MAX) x = CAIRO_RECT_INT_MAX; - if (y < 0) y = 0; - if (y > CAIRO_RECT_INT_MAX) y = CAIRO_RECT_INT_MAX; - lx = floor (x); rx = ceil (x); - ty = floor (y); by = ceil (y); - if (!set) { - left = lx; - right = rx; - top = ty; - bottom = by; - set = TRUE; - } else { - if (lx < left) left = lx; - if (rx > right) right = rx; - if (ty < top) top = ty; - if (by > bottom) bottom = by; - } - } - } - extents->x = left; extents->width = right - left; - extents->y = top; extents->height = bottom - top; + _cairo_matrix_transform_bounding_box (&imatrix, + &x1, &y1, &x2, &y2, + NULL); + + x1 = floor (x1); + if (x1 < 0) + x1 = 0; + y1 = floor (y1); + if (y1 < 0) + y1 = 0; + + x2 = ceil (x2); + if (x2 > CAIRO_RECT_INT_MAX) + x2 = CAIRO_RECT_INT_MAX; + y2 = ceil (y2); + if (y2 > CAIRO_RECT_INT_MAX) + y2 = CAIRO_RECT_INT_MAX; + + extents->x = x1; extents->width = x2 - x1; + extents->y = y1; extents->height = y2 - y1; + return CAIRO_STATUS_SUCCESS; } diff --git a/gfx/cairo/cairo/src/cairo-pdf-operators.c b/gfx/cairo/cairo/src/cairo-pdf-operators.c index 1dbb08c6173..1198b4ef270 100644 --- a/gfx/cairo/cairo/src/cairo-pdf-operators.c +++ b/gfx/cairo/cairo/src/cairo-pdf-operators.c @@ -946,7 +946,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators, _cairo_output_stream_printf (word_wrap_stream, "%f %f Td ", (glyphs[i].x - Tlm_x)/scaled_font->scale.xx, - (glyphs[i].y - Tlm_y)/-scaled_font->scale.yy); + (glyphs[i].y - Tlm_y)/scaled_font->scale.yy); Tlm_x = glyphs[i].x; Tlm_y = glyphs[i].y; Tm_x = Tlm_x; diff --git a/gfx/cairo/cairo/src/cairo-pdf-surface.c b/gfx/cairo/cairo/src/cairo-pdf-surface.c index ce6d8c4a6a3..4fb359642dc 100644 --- a/gfx/cairo/cairo/src/cairo-pdf-surface.c +++ b/gfx/cairo/cairo/src/cairo-pdf-surface.c @@ -211,6 +211,18 @@ _cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface, object->offset = _cairo_output_stream_get_position (surface->output); } +static void +cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface, + double width, + double height) +{ + surface->width = width; + surface->height = height; + cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height); + _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, + &surface->cairo_to_pdf); +} + static cairo_surface_t * _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, double width, @@ -442,11 +454,9 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface, return; } - pdf_surface->width = width_in_points; - pdf_surface->height = height_in_points; - cairo_matrix_init (&pdf_surface->cairo_to_pdf, 1, 0, 0, -1, 0, height_in_points); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&pdf_surface->pdf_operators, - &pdf_surface->cairo_to_pdf); + cairo_pdf_surface_set_size_internal (pdf_surface, + width_in_points, + height_in_points); status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface, width_in_points, height_in_points); @@ -731,6 +741,8 @@ _cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group) cairo_pattern_destroy (group->source); if (group->mask) cairo_pattern_destroy (group->mask); + if (group->glyphs) + free (group->glyphs); if (group->scaled_font) cairo_scaled_font_destroy (group->scaled_font); free (group); @@ -1481,7 +1493,6 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, cairo_pdf_resource_t *resource) { double old_width, old_height; - cairo_matrix_t old_cairo_to_pdf; cairo_paginated_mode_t old_paginated_mode; cairo_clip_t *old_clip; cairo_rectangle_int_t meta_extents; @@ -1494,20 +1505,16 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, old_width = surface->width; old_height = surface->height; - old_cairo_to_pdf = surface->cairo_to_pdf; old_paginated_mode = surface->paginated_mode; old_clip = _cairo_surface_get_clip (&surface->base); - surface->width = meta_extents.width; - surface->height = meta_extents.height; + cairo_pdf_surface_set_size_internal (surface, + meta_extents.width, + meta_extents.height); /* Patterns are emitted after fallback images. The paginated mode * needs to be set to _RENDER while the meta surface is replayed * back to this surface. */ surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER; - cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, surface->height); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_pdf); - _cairo_pdf_group_resources_clear (&surface->resources); status = _cairo_pdf_surface_open_content_stream (surface, TRUE); if (status) @@ -1535,17 +1542,14 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, status = _cairo_pdf_surface_close_content_stream (surface); CLEANUP_GROUP: - surface->width = old_width; - surface->height = old_height; + cairo_pdf_surface_set_size_internal (surface, + old_width, + old_height); surface->paginated_mode = old_paginated_mode; - surface->cairo_to_pdf = old_cairo_to_pdf; status2 = _cairo_surface_set_clip (&surface->base, old_clip); if (status == CAIRO_STATUS_SUCCESS) status = status2; - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_pdf); - return status; } @@ -2515,8 +2519,9 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern old_width = surface->width; old_height = surface->height; - surface->width = pdf_pattern->width; - surface->height = pdf_pattern->height; + cairo_pdf_surface_set_size_internal (surface, + pdf_pattern->width, + pdf_pattern->height); switch (pdf_pattern->pattern->type) { case CAIRO_PATTERN_TYPE_SOLID: @@ -2542,8 +2547,9 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern break; } - surface->width = old_width; - surface->height = old_height; + cairo_pdf_surface_set_size_internal (surface, + old_width, + old_height); return status; } @@ -3821,18 +3827,13 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface, cairo_pdf_smask_group_t *group) { double old_width, old_height; - cairo_matrix_t old_cairo_to_pdf; cairo_status_t status; old_width = surface->width; old_height = surface->height; - old_cairo_to_pdf = surface->cairo_to_pdf; - surface->width = group->width; - surface->height = group->height; - cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, surface->height); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_pdf); - + cairo_pdf_surface_set_size_internal (surface, + group->width, + group->height); /* _mask is a special case that requires two groups - source * and mask as well as a smask and gstate dictionary */ if (group->operation == PDF_MASK) @@ -3883,11 +3884,9 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface, _cairo_pdf_surface_unselect_pattern (surface); status = _cairo_pdf_surface_close_group (surface, NULL); - surface->width = old_width; - surface->height = old_height; - surface->cairo_to_pdf = old_cairo_to_pdf; - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_pdf); + cairo_pdf_surface_set_size_internal (surface, + old_width, + old_height); return status; } @@ -4627,7 +4626,12 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, group->operation = PDF_SHOW_GLYPHS; group->source = cairo_pattern_reference (source); group->source_res = pattern_res; - group->glyphs = glyphs; + group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); + if (group->glyphs == NULL) { + _cairo_pdf_smask_group_destroy (group); + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } + memcpy (group->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); group->num_glyphs = num_glyphs; group->scaled_font = cairo_scaled_font_reference (scaled_font); status = _cairo_pdf_surface_add_smask_group (surface, group); diff --git a/gfx/cairo/cairo/src/cairo-ps-surface.c b/gfx/cairo/cairo/src/cairo-ps-surface.c index e78e24738e1..54f5afec344 100644 --- a/gfx/cairo/cairo/src/cairo-ps-surface.c +++ b/gfx/cairo/cairo/src/cairo-ps-surface.c @@ -183,7 +183,8 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface) " { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse\n" " } forall\n" "} bind def\n" - "/Td { moveto } bind def\n" + "/Td { matrix translate cairo_font_matrix matrix concatmatrix dup\n" + " /cairo_font_matrix exch def cairo_font exch selectfont 0 0 moveto } bind def\n" "/Tm { 6 array astore dup /cairo_font_matrix exch def\n" " cairo_font exch selectfont 0 0 moveto } bind def\n" "/g { setgray } bind def\n" diff --git a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c index f74c89b3642..ee29f89aa7e 100644 --- a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c +++ b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c @@ -339,6 +339,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, scaled_font_glyph_index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); + assert (status != CAIRO_INT_STATUS_UNSUPPORTED); if (status) return status; @@ -544,11 +545,21 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, } /* Glyph not found. Determine whether the glyph is outline or - * bitmap and add to the appropriate subset */ - status = _cairo_scaled_glyph_lookup (scaled_font, - scaled_font_glyph_index, - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); + * bitmap and add to the appropriate subset. + * + * glyph_index 0 (the .notdef glyph) is a special case. Some fonts + * will return CAIRO_INT_STATUS_UNSUPPORTED when doing a + * _scaled_glyph_lookup(_GLYPH_INFO_PATH). Type1-fallback creates + * empty glyphs in this case so we can put the glyph in a unscaled + * subset. */ + if (scaled_font_glyph_index == 0) { + status = CAIRO_STATUS_SUCCESS; + } else { + status = _cairo_scaled_glyph_lookup (scaled_font, + scaled_font_glyph_index, + CAIRO_SCALED_GLYPH_INFO_PATH, + &scaled_glyph); + } if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) return status; diff --git a/gfx/cairo/cairo/src/cairo-surface.c b/gfx/cairo/cairo/src/cairo-surface.c index a72428345d4..12b08850c3f 100644 --- a/gfx/cairo/cairo/src/cairo-surface.c +++ b/gfx/cairo/cairo/src/cairo-surface.c @@ -887,6 +887,9 @@ slim_hidden_def (cairo_surface_get_device_offset); * there is currently no way to have more than one fallback resolution * in effect on a single page. * + * The default fallback resoultion is 300 pixels per inch in both + * dimensions. + * * Since: 1.2 **/ void diff --git a/gfx/cairo/cairo/src/cairo-truetype-subset.c b/gfx/cairo/cairo/src/cairo-truetype-subset.c index 3fa174c8287..c3f0b0568b2 100644 --- a/gfx/cairo/cairo/src/cairo-truetype-subset.c +++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c @@ -34,6 +34,12 @@ * Adrian Johnson */ +/* + * Useful links: + * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html + * http://www.microsoft.com/typography/specs/default.htm + */ + #define _BSD_SOURCE /* for snprintf(), strdup() */ #include "cairoint.h" @@ -499,27 +505,30 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, unsigned long size) { tt_glyph_data_t *glyph_data; - tt_composite_glyph_t *composite_glyph, *last_glyph; + tt_composite_glyph_t *composite_glyph; int num_args; int has_more_components; unsigned short flags; unsigned short index; cairo_status_t status; + unsigned char *end = buffer + size; if (font->status) return font->status; - if (size < sizeof (tt_glyph_data_t)) + glyph_data = (tt_glyph_data_t *) buffer; + if ((unsigned char *)(&glyph_data->data) >= end) return CAIRO_INT_STATUS_UNSUPPORTED; - glyph_data = (tt_glyph_data_t *) buffer; if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0) return CAIRO_STATUS_SUCCESS; composite_glyph = &glyph_data->glyph; - last_glyph = (tt_composite_glyph_t *) (buffer + size); do { - flags = be16_to_cpu (composite_glyph->flags); + if ((unsigned char *)(&composite_glyph->args[1]) >= end) + return CAIRO_INT_STATUS_UNSUPPORTED; + + flags = be16_to_cpu (composite_glyph->flags); has_more_components = flags & TT_MORE_COMPONENTS; status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index); if (status) @@ -536,9 +545,6 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, else if (flags & TT_WE_HAVE_A_TWO_BY_TWO) num_args += 3; composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]); - - if (has_more_components && composite_glyph >= last_glyph) - return CAIRO_INT_STATUS_UNSUPPORTED; } while (has_more_components); return CAIRO_STATUS_SUCCESS; @@ -1079,7 +1085,8 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { unsigned short parent_glyph = font->scaled_font_subset->glyphs[i]; status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph); - assert (status == CAIRO_STATUS_SUCCESS); + if (status) + goto fail1; } cairo_truetype_font_create_truetype_table_list (font); diff --git a/gfx/cairo/cairo/src/cairo-type1-fallback.c b/gfx/cairo/cairo/src/cairo-type1-fallback.c index a0fe5da6c1b..539ddf22784 100644 --- a/gfx/cairo/cairo/src/cairo-type1-fallback.c +++ b/gfx/cairo/cairo/src/cairo-type1-fallback.c @@ -331,33 +331,6 @@ charstring_encrypt (cairo_array_t *data) } } -static cairo_int_status_t -create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type) -{ - cairo_status_t status; - - /* We're passing constants below, so we know the 0 values will - * only use 1 byte each, and the 500 values will use 2 bytes - * each. Then 2 more for each of the commands is 10 total. */ - status = _cairo_array_grow_by (data, 10); - if (status) - return status; - - if (type == CAIRO_CHARSTRING_TYPE1) { - charstring_encode_integer (data, 0, type); - charstring_encode_integer (data, 0, type); - - /* The width is arbitrary. */ - charstring_encode_integer (data, 500, type); - charstring_encode_integer (data, 0, type); - charstring_encode_command (data, CHARSTRING_sbw); - } - - charstring_encode_command (data, CHARSTRING_endchar); - - return CAIRO_STATUS_SUCCESS; -} - static cairo_int_status_t cairo_type1_font_create_charstring (cairo_type1_font_t *font, int subset_index, @@ -369,6 +342,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, cairo_scaled_glyph_t *scaled_glyph; t1_path_info_t path_info; cairo_text_extents_t *metrics; + cairo_bool_t emit_path = TRUE; /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */ status = _cairo_scaled_glyph_lookup (font->type1_scaled_font, @@ -376,6 +350,16 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_PATH, &scaled_glyph); + + /* It is ok for the .notdef glyph to not have a path available. We + * just need the metrics to emit an empty glyph. */ + if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) { + emit_path = FALSE; + status = _cairo_scaled_glyph_lookup (font->type1_scaled_font, + glyph_index, + CAIRO_SCALED_GLYPH_INFO_METRICS, + &scaled_glyph); + } if (status) return status; @@ -411,22 +395,24 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, path_info.current_x = (int) scaled_glyph->metrics.x_bearing; path_info.current_y = (int) scaled_glyph->metrics.y_bearing; } else { - charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type); + charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type); path_info.current_x = 0; path_info.current_y = 0; } path_info.data = data; path_info.type = type; - status = _cairo_path_fixed_interpret (scaled_glyph->path, - CAIRO_DIRECTION_FORWARD, - _charstring_move_to, - _charstring_line_to, - _charstring_curve_to, - _charstring_close_path, - &path_info); - if (status) - return status; + if (emit_path) { + status = _cairo_path_fixed_interpret (scaled_glyph->path, + CAIRO_DIRECTION_FORWARD, + _charstring_move_to, + _charstring_line_to, + _charstring_curve_to, + _charstring_close_path, + &path_info); + if (status) + return status; + } status = _cairo_array_grow_by (data, 1); if (status) @@ -455,7 +441,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, "2 index /CharStrings %d dict dup begin\n", font->scaled_font_subset->num_glyphs + 1); - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { + for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { _cairo_array_truncate (&data, 0); /* four "random" bytes required by encryption algorithm */ status = _cairo_array_append_multiple (&data, zeros, 4); @@ -473,6 +459,8 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, _cairo_output_stream_printf (encrypted_output, "/%s %d RD ", font->scaled_font_subset->glyph_names[i], length); + } else if (i == 0) { + _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length); } else { _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length); } @@ -482,24 +470,6 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, _cairo_output_stream_printf (encrypted_output, " ND\n"); } - /* All type 1 fonts must have a /.notdef charstring */ - - _cairo_array_truncate (&data, 0); - /* four "random" bytes required by encryption algorithm */ - status = _cairo_array_append_multiple (&data, zeros, 4); - if (status) - goto fail; - status = create_notdef_charstring (&data, CAIRO_CHARSTRING_TYPE1); - if (status) - goto fail; - charstring_encrypt (&data); - length = _cairo_array_num_elements (&data); - _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length); - _cairo_output_stream_write (encrypted_output, - _cairo_array_index (&data, 0), - length); - _cairo_output_stream_printf (encrypted_output, " ND\n"); - fail: _cairo_array_fini (&data); return status; @@ -856,14 +826,10 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset, if (status) goto fail2; - if (i == 0) { - status = create_notdef_charstring (&charstring, CAIRO_CHARSTRING_TYPE2); - } else { - status = cairo_type1_font_create_charstring (font, i, - font->scaled_font_subset->glyphs[i], - CAIRO_CHARSTRING_TYPE2, - &charstring); - } + status = cairo_type1_font_create_charstring (font, i, + font->scaled_font_subset->glyphs[i], + CAIRO_CHARSTRING_TYPE2, + &charstring); if (status) goto fail2; diff --git a/gfx/cairo/cairo/src/cairo-type1-subset.c b/gfx/cairo/cairo/src/cairo-type1-subset.c index 6afd4cdf6fe..4d6c8dfb2fc 100644 --- a/gfx/cairo/cairo/src/cairo-type1-subset.c +++ b/gfx/cairo/cairo/src/cairo-type1-subset.c @@ -33,6 +33,11 @@ * Kristian Høgsberg */ +/* + * Useful links: + * http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF + */ + #define _BSD_SOURCE /* for snprintf(), strdup() */ #include "cairoint.h" #include "cairo-type1-private.h" diff --git a/gfx/cairo/cairo/src/cairo-xlib-display.c b/gfx/cairo/cairo/src/cairo-xlib-display.c index d69b738d48f..609b3ba4a13 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-display.c +++ b/gfx/cairo/cairo/src/cairo-xlib-display.c @@ -300,6 +300,17 @@ _cairo_xlib_display_get (Display *dpy) * back up to 6.7 or 6.8. */ if (VendorRelease (dpy) >= 60700000 && VendorRelease (dpy) <= 60802000) display->buggy_repeat = TRUE; + + /* But even the new modular server has bugs, (bad enough to + * crash the X server), that it so happens we can avoid with + * the exact same buggy_repeat workaround. We've verified that + * this bug exists as least as late as version 1.3.0.0, (which + * is in Fedora 8), and is gone again in version 1.4.99.901 + * (from a Fedora 9 Beta). Versions between those are still + * unknown, but until we learn more, we'll assume that any 1.3 + * version is buggy. */ + if (VendorRelease (dpy) < 10400000) + display->buggy_repeat = TRUE; } else if (strstr (ServerVendor (dpy), "XFree86") != NULL) { if (VendorRelease (dpy) <= 40500000) display->buggy_repeat = TRUE; diff --git a/gfx/cairo/cairo/src/cairo-xlib-surface.c b/gfx/cairo/cairo/src/cairo-xlib-surface.c index df80ca69883..48b7550dafb 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-surface.c +++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c @@ -2925,6 +2925,20 @@ _cairo_xlib_surface_add_glyph (Display *dpy, already_had_glyph_surface = TRUE; } + /* XXX XRenderAddGlyph does not handle a glyph surface larger than the + * maximum XRequest size. + */ + { + /* pessimistic length estimation in case we need to change formats */ + int len = 4 * glyph_surface->width * glyph_surface->height; + int max_request_size = XMaxRequestSize (dpy) - + sz_xRenderAddGlyphsReq - + sz_xGlyphInfo - + 4; + if (len >= max_request_size) + return CAIRO_INT_STATUS_UNSUPPORTED; + } + if (scaled_font->surface_private == NULL) { status = _cairo_xlib_surface_font_init (dpy, scaled_font); if (status) diff --git a/gfx/cairo/cairo/src/cairo.c b/gfx/cairo/cairo/src/cairo.c index b540af3c2a0..a7073d0f182 100644 --- a/gfx/cairo/cairo/src/cairo.c +++ b/gfx/cairo/cairo/src/cairo.c @@ -634,9 +634,7 @@ slim_hidden_def(cairo_pop_group_to_source); * operations. See #cairo_operator_t for details on the semantics of * each available compositing operator. * - * XXX: I'd also like to direct the reader's attention to some - * (not-yet-written) section on cairo's imaging model. How would I do - * that if such a section existed? (cworth). + * The default operator is %CAIRO_OPERATOR_OVER. **/ void cairo_set_operator (cairo_t *cr, cairo_operator_t op) @@ -666,6 +664,9 @@ slim_hidden_def (cairo_set_operator); * The color components are floating point numbers in the range 0 to * 1. If the values passed in are outside that range, they will be * clamped. + * + * The default source pattern is opaque black, (that is, it is + * equivalent to cairo_set_source_rgb (cr, 0.0, 0.0, 0.0)). **/ void cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) @@ -698,6 +699,9 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) * The color and alpha components are floating point numbers in the * range 0 to 1. If the values passed in are outside that range, they * will be clamped. + * + * The default source pattern is opaque black, (that is, it is + * equivalent to cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0)). **/ void cairo_set_source_rgba (cairo_t *cr, @@ -780,9 +784,9 @@ slim_hidden_def (cairo_set_source_surface); * that further modifications of the current transformation matrix * will not affect the source pattern. See cairo_pattern_set_matrix(). * - * XXX: I'd also like to direct the reader's attention to some - * (not-yet-written) section on cairo's imaging model. How would I do - * that if such a section existed? (cworth). + * The default source pattern is a solid pattern that is opaque black, + * (that is, it is equivalent to cairo_set_source_rgb (cr, 0.0, 0.0, + * 0.0)). **/ void cairo_set_source (cairo_t *cr, cairo_pattern_t *source) @@ -891,6 +895,8 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) * (potentially self-intersecting) path. The current fill rule affects * both cairo_fill() and cairo_clip(). See #cairo_fill_rule_t for details * on the semantics of each available fill rule. + * + * The default fill rule is %CAIRO_FILL_RULE_WINDING. **/ void cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) @@ -959,6 +965,8 @@ cairo_set_line_width (cairo_t *cr, double width) * examined by cairo_stroke(), cairo_stroke_extents(), and * cairo_stroke_to_path(), but does not have any effect during path * construction. + * + * The default line cap style is %CAIRO_LINE_CAP_BUTT. **/ void cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) @@ -976,7 +984,7 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) /** * cairo_set_line_join: * @cr: a cairo context - * @line_join: a line joint style + * @line_join: a line join style * * Sets the current line join style within the cairo context. See * #cairo_line_join_t for details about how the available line join @@ -986,6 +994,8 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) * examined by cairo_stroke(), cairo_stroke_extents(), and * cairo_stroke_to_path(), but does not have any effect during path * construction. + * + * The default line join style is %CAIRO_LINE_JOIN_MITER. **/ void cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) @@ -1116,6 +1126,15 @@ cairo_get_dash (cairo_t *cr, * examined by cairo_stroke(), cairo_stroke_extents(), and * cairo_stroke_to_path(), but does not have any effect during path * construction. + * + * The default miter limit value is 10.0, which will convert joins + * with interior angles less than 11 degrees to bevels instead of + * miters. For reference, a miter limit of 2.0 makes the miter cutoff + * at 60 degrees, and a miter limit of 1.414 makes the cutoff at 90 + * degrees. + * + * A miter limit for a desired angle can be computed as: miter limit = + * 1/sin(angle/2) **/ void cairo_set_miter_limit (cairo_t *cr, double limit) @@ -2571,13 +2590,38 @@ cairo_copy_clip_rectangle_list (cairo_t *cr) * @slant: the slant for the font * @weight: the weight for the font * + * Note: The cairo_select_font_face() function call is part of what + * the cairo designers call the "toy" text API. It is convenient for + * short demos and simple programs, but it is not expected to be + * adequate for serious text-using applications. + * * Selects a family and style of font from a simplified description as - * a family name, slant and weight. This function is meant to be used - * only for applications with simple font needs: Cairo doesn't provide - * for operations such as listing all available fonts on the system, - * and it is expected that most applications will need to use a more - * comprehensive font handling and text layout library in addition to - * cairo. + * a family name, slant and weight. Cairo provides no operation to + * list available family names on the system (this is a "toy", + * remember"), but the standard CSS2 generic family names, ("serif", + * "sans-serif", "cursive", "fantasy", "monospace"), are likely to + * work as expected. + * + * For "real" font selection, see the font-backend-specific + * font_face_create functions for the font backend you are using. (For + * example, if you are using the freetype-based cairo-ft font backend, + * see cairo_ft_font_face_create_for_ft_face() or + * cairo_ft_font_face_create_for_pattern().) The resulting font face + * could then be used with cairo_scaled_font_create() and + * cairo_set_scaled_font(). + * + * Similarly, when using the "real" font support, you can call + * directly into the underlying font system, (such as fontconfig or + * freetype), for operations such as listing available fonts, etc. + * + * It is expected that most applications will need to use a more + * comprehensive font handling and text layout library, (for example, + * pango), in conjunction with cairo. + * + * If text is drawn without a call to cairo_select_font_face(), (nor + * cairo_set_font_face() nor cairo_set_scaled_font()), the default + * family is "sans", slant is %CAIRO_FONT_SLANT_NORMAL, and weight is + * %CAIRO_FONT_WEIGHT_NORMAL. **/ void cairo_select_font_face (cairo_t *cr, @@ -2692,6 +2736,10 @@ cairo_get_font_face (cairo_t *cr) * cairo_set_font_matrix(). This results in a font size of @size user space * units. (More precisely, this matrix will result in the font's * em-square being a @size by @size square in user space.) + * + * If text is drawn without a call to cairo_set_font_size(), (nor + * cairo_set_font_matrix() nor cairo_set_scaled_font()), the default + * font size is 10.0. **/ void cairo_set_font_size (cairo_t *cr, double size) diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h index ab730e7ad9b..4a3a773df88 100644 --- a/gfx/cairo/cairo/src/cairo.h +++ b/gfx/cairo/cairo/src/cairo.h @@ -373,6 +373,8 @@ cairo_pop_group_to_source (cairo_t *cr); * #cairo_operator_t is used to set the compositing operator for all cairo * drawing operations. * + * The default operator is %CAIRO_OPERATOR_OVER. + * * The operators marked as unbounded modify their * destination even outside of the mask layer (that is, their effect is not * bound by the mask layer). However, their effect can still be limited by @@ -473,6 +475,8 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias); * (Note that filling is not actually implemented in this way. This * is just a description of the rule that is applied.) * + * The default fill rule is %CAIRO_FILL_RULE_WINDING. + * * New entries may be added in future versions. **/ typedef enum _cairo_fill_rule { @@ -492,7 +496,9 @@ cairo_set_line_width (cairo_t *cr, double width); * @CAIRO_LINE_CAP_ROUND: use a round ending, the center of the circle is the end point * @CAIRO_LINE_CAP_SQUARE: use squared ending, the center of the square is the end point * - * Specifies how to render the endpoint of a line when stroking. + * Specifies how to render the endpoints of the path when stroking. + * + * The default line cap style is %CAIRO_LINE_CAP_BUTT. **/ typedef enum _cairo_line_cap { CAIRO_LINE_CAP_BUTT, @@ -513,6 +519,8 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap); * the line width from the joint point * * Specifies how to render the junction of two lines when stroking. + * + * The default line join style is %CAIRO_LINE_JOIN_MITER. **/ typedef enum _cairo_line_join { CAIRO_LINE_JOIN_MITER, @@ -1789,13 +1797,18 @@ cairo_pattern_get_matrix (cairo_pattern_t *pattern, * are fully transparent * @CAIRO_EXTEND_REPEAT: the pattern is tiled by repeating * @CAIRO_EXTEND_REFLECT: the pattern is tiled by reflecting - * at the edges (not implemented for surface patterns currently) + * at the edges (Implemented for surface patterns since 1.6) * @CAIRO_EXTEND_PAD: pixels outside of the pattern copy - * the closest pixel from the source (Since 1.2; not implemented - * for surface patterns currently) + * the closest pixel from the source (Since 1.2; but only + * implemented for surface patterns since 1.6) * - * #cairo_extend_t is used to describe how the area outside - * of a pattern will be drawn. + * #cairo_extend_t is used to describe how pattern color/alpha will be + * determined for areas "outside" the pattern's natural area, (for + * example, outside the surface bounds or outside the gradient + * geometry). + * + * The default extend mode is %CAIRO_EXTEND_NONE for surface patterns + * and %CAIRO_EXTEND_PAD for gradient patterns. * * New entries may be added in future versions. **/ diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h index 8ea3e4934e6..e1bdb4e8cd2 100644 --- a/gfx/cairo/cairo/src/cairoint.h +++ b/gfx/cairo/cairo/src/cairoint.h @@ -768,7 +768,7 @@ struct _cairo_color { #define CAIRO_EXTEND_SURFACE_DEFAULT CAIRO_EXTEND_NONE #define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD -#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST +#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_GOOD struct _cairo_pattern { cairo_pattern_type_t type; diff --git a/gfx/cairo/libpixman/src/pixman-combine.c b/gfx/cairo/libpixman/src/pixman-combine.c index be08af4352f..d2017362d49 100644 --- a/gfx/cairo/libpixman/src/pixman-combine.c +++ b/gfx/cairo/libpixman/src/pixman-combine.c @@ -13,7 +13,6 @@ * this difference will have two versions using the same convention. */ - /* * Combine src and mask */ @@ -1210,6 +1209,7 @@ static CombineFuncU pixman_fbCombineFuncU[] = { fbCombineConjointAtopU, fbCombineConjointAtopReverseU, fbCombineConjointXorU, + NULL /* Noop */ }; static CombineFuncC pixman_fbCombineFuncC[] = { @@ -1257,6 +1257,7 @@ static CombineFuncC pixman_fbCombineFuncC[] = { fbCombineConjointAtopC, fbCombineConjointAtopReverseC, fbCombineConjointXorC, + NULL /* Noop */ }; FbComposeFunctions pixman_composeFunctions = { diff --git a/gfx/cairo/libpixman/src/pixman-image.c b/gfx/cairo/libpixman/src/pixman-image.c index 9b6846e16ec..30c294b880c 100644 --- a/gfx/cairo/libpixman/src/pixman-image.c +++ b/gfx/cairo/libpixman/src/pixman-image.c @@ -717,3 +717,87 @@ pixman_image_fill_rectangles (pixman_op_t op, return TRUE; } + +pixman_bool_t +pixman_image_can_get_solid (pixman_image_t *image) +{ + if (image->type == SOLID) + return TRUE; + + if (image->type != BITS || + image->bits.width != 1 || + image->bits.height != 1) + { + return FALSE; + } + + if (image->common.repeat != PIXMAN_REPEAT_NORMAL) + return FALSE; + + switch (image->bits.format) + { + case PIXMAN_a8r8g8b8: + case PIXMAN_x8r8g8b8: + case PIXMAN_a8b8g8r8: + case PIXMAN_x8b8g8r8: + case PIXMAN_r8g8b8: + case PIXMAN_b8g8r8: + case PIXMAN_r5g6b5: + case PIXMAN_b5g6r5: + return TRUE; + default: + return FALSE; + } +} + +pixman_bool_t +pixman_image_is_opaque(pixman_image_t *image) +{ + int i = 0; + int gradientNumberOfColors = 0; + + if(image->common.alpha_map) + return FALSE; + + switch(image->type) + { + case BITS: + if(PIXMAN_FORMAT_A(image->bits.format)) + return FALSE; + break; + + case LINEAR: + case CONICAL: + case RADIAL: + gradientNumberOfColors = image->gradient.n_stops; + i=0; + while(igradient.stops[i].color.alpha != 0xffff) + return FALSE; + i++; + } + break; + + case SOLID: + if(Alpha(image->solid.color) != 0xff) + return FALSE; + break; + } + + /* Convolution filters can introduce translucency if the sum of the weights + is lower than 1. */ + if (image->common.filter == PIXMAN_FILTER_CONVOLUTION) + return FALSE; + + if (image->common.repeat == PIXMAN_REPEAT_NONE) + { + if (image->common.filter != PIXMAN_FILTER_NEAREST) + return FALSE; + + if (image->common.transform) + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/gfx/cairo/libpixman/src/pixman-pict.c b/gfx/cairo/libpixman/src/pixman-pict.c index b7c0773f25b..f01a6432da6 100644 --- a/gfx/cairo/libpixman/src/pixman-pict.c +++ b/gfx/cairo/libpixman/src/pixman-pict.c @@ -1261,38 +1261,6 @@ pixman_walk_composite_region (pixman_op_t op, pixman_region_fini (®); } -static pixman_bool_t -can_get_solid (pixman_image_t *image) -{ - if (image->type == SOLID) - return TRUE; - - if (image->type != BITS || - image->bits.width != 1 || - image->bits.height != 1) - { - return FALSE; - } - - if (image->common.repeat != PIXMAN_REPEAT_NORMAL) - return FALSE; - - switch (image->bits.format) - { - case PIXMAN_a8r8g8b8: - case PIXMAN_x8r8g8b8: - case PIXMAN_a8b8g8r8: - case PIXMAN_x8b8g8r8: - case PIXMAN_r8g8b8: - case PIXMAN_b8g8r8: - case PIXMAN_r5g6b5: - case PIXMAN_b5g6r5: - return TRUE; - default: - return FALSE; - } -} - #define SCANLINE_BUFFER_LENGTH 2048 static void @@ -1554,7 +1522,7 @@ get_fast_path (const FastPathInfo *fast_paths, if (info->op != op) continue; - if ((info->src_format == PIXMAN_solid && can_get_solid (pSrc)) || + if ((info->src_format == PIXMAN_solid && pixman_image_can_get_solid (pSrc)) || (pSrc->type == BITS && info->src_format == pSrc->bits.format)) { valid_src = TRUE; @@ -1596,6 +1564,82 @@ get_fast_path (const FastPathInfo *fast_paths, return NULL; } +/* + * Operator optimizations based on source or destination opacity + */ +typedef struct +{ + pixman_op_t op; + pixman_op_t opSrcDstOpaque; + pixman_op_t opSrcOpaque; + pixman_op_t opDstOpaque; +} OptimizedOperatorInfo; + +static const OptimizedOperatorInfo optimized_operators[] = +{ + /* Input Operator SRC&DST Opaque SRC Opaque DST Opaque */ + { PIXMAN_OP_OVER, PIXMAN_OP_SRC, PIXMAN_OP_SRC, PIXMAN_OP_OVER }, + { PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST }, + { PIXMAN_OP_IN, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_SRC }, + { PIXMAN_OP_IN_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_DST, PIXMAN_OP_IN_REVERSE }, + { PIXMAN_OP_OUT, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_CLEAR }, + { PIXMAN_OP_OUT_REVERSE, PIXMAN_OP_CLEAR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT_REVERSE }, + { PIXMAN_OP_ATOP, PIXMAN_OP_SRC, PIXMAN_OP_IN, PIXMAN_OP_OVER }, + { PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_IN_REVERSE }, + { PIXMAN_OP_XOR, PIXMAN_OP_CLEAR, PIXMAN_OP_OUT, PIXMAN_OP_OUT_REVERSE }, + { PIXMAN_OP_SATURATE, PIXMAN_OP_DST, PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST }, + { PIXMAN_OP_NONE } +}; + + +/* + * Check if the current operator could be optimized + */ +static const OptimizedOperatorInfo* +pixman_operator_can_be_optimized(pixman_op_t op) +{ + const OptimizedOperatorInfo *info; + + for (info = optimized_operators; info->op != PIXMAN_OP_NONE; info++) + { + if(info->op == op) + return info; + } + return NULL; +} + +/* + * Optimize the current operator based on opacity of source or destination + * The output operator should be mathematically equivalent to the source. + */ +static pixman_op_t +pixman_optimize_operator(pixman_op_t op, pixman_image_t *pSrc, pixman_image_t *pMask, pixman_image_t *pDst ) +{ + pixman_bool_t is_source_opaque; + pixman_bool_t is_dest_opaque; + const OptimizedOperatorInfo *info = pixman_operator_can_be_optimized(op); + + if(!info || pMask) + return op; + + is_source_opaque = pixman_image_is_opaque(pSrc); + is_dest_opaque = pixman_image_is_opaque(pDst); + + if(is_source_opaque == FALSE && is_dest_opaque == FALSE) + return op; + + if(is_source_opaque && is_dest_opaque) + return info->opSrcDstOpaque; + else if(is_source_opaque) + return info->opSrcOpaque; + else if(is_dest_opaque) + return info->opDstOpaque; + + return op; + +} + + void pixman_image_composite (pixman_op_t op, pixman_image_t * pSrc, @@ -1652,7 +1696,15 @@ pixman_image_composite (pixman_op_t op, } } - if ((pSrc->type == BITS || can_get_solid (pSrc)) && (!pMask || pMask->type == BITS) + /* + * Check if we can replace our operator by a simpler one if the src or dest are opaque + * The output operator should be mathematically equivalent to the source. + */ + op = pixman_optimize_operator(op, pSrc, pMask, pDst); + if(op == PIXMAN_OP_DST) + return; + + if ((pSrc->type == BITS || pixman_image_can_get_solid (pSrc)) && (!pMask || pMask->type == BITS) && !srcTransform && !maskTransform && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION) @@ -1753,6 +1805,7 @@ pixman_image_composite (pixman_op_t op, } + #ifdef USE_MMX /* The CPU detection code needs to be in a file not compiled with * "-mmmx -msse", as gcc would generate CMOV instructions otherwise diff --git a/gfx/cairo/libpixman/src/pixman-private.h b/gfx/cairo/libpixman/src/pixman-private.h index 921dd229a9c..a730381bfc0 100644 --- a/gfx/cairo/libpixman/src/pixman-private.h +++ b/gfx/cairo/libpixman/src/pixman-private.h @@ -839,6 +839,12 @@ pixman_rasterize_edges_accessors (pixman_image_t *image, pixman_fixed_t t, pixman_fixed_t b); +pixman_bool_t +pixman_image_is_opaque(pixman_image_t *image); + +pixman_bool_t +pixman_image_can_get_solid (pixman_image_t *image); + #ifdef PIXMAN_TIMING