зеркало из https://github.com/mozilla/pjs.git
b=419715, upgrade cairo to 1.6 or as-close-as-possible -- imported patch cairo-upgrade-more.patch ; r=me
This commit is contained in:
Родитель
ebd87cd7e8
Коммит
7ffac589e5
|
@ -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 *****
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
* Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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,26 +505,29 @@ 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 {
|
||||
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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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,13 +395,14 @@ 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;
|
||||
if (emit_path) {
|
||||
status = _cairo_path_fixed_interpret (scaled_glyph->path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_charstring_move_to,
|
||||
|
@ -427,6 +412,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
|||
&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);
|
||||
}
|
||||
if (status)
|
||||
goto fail2;
|
||||
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <firstterm>unbounded</firstterm> 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.
|
||||
**/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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(i<gradientNumberOfColors)
|
||||
{
|
||||
if(image->gradient.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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче