зеркало из https://github.com/mozilla/pjs.git
Upgrade cairo to latest cairo trunk, along with some still-in-review patches
This commit is contained in:
Родитель
71e7b476c8
Коммит
e882f0f837
|
@ -10,14 +10,27 @@ http://www.cairographics.org/.
|
|||
|
||||
VERSIONS:
|
||||
|
||||
cairo 1.1.1 (cvs)
|
||||
glitz 0.5.0
|
||||
cairo 1.1.1 (cvs - 2006-01-10)
|
||||
glitz 0.5.2 (cvs - 2006-01-10)
|
||||
|
||||
***** NOTE FOR VISUAL C++ 6.0 *****
|
||||
|
||||
VC6 cannot build pixman from cairo. Therefore, VC6 builds are not supported
|
||||
if cairo is enabled. Please upgrade to VC7.1/8.
|
||||
|
||||
==== Patches ====
|
||||
|
||||
win32-glyph-path.diff - upstream merged patch, fixes glyph->path conversion.
|
||||
mozilla-misc.patch
|
||||
- Misc compilation fixes for pixman (submitted upstream)
|
||||
- temporary moz_cairo_set_target API (not for upstream)
|
||||
|
||||
cairo-debug-helpers.patch
|
||||
- some stuff for cairo-debug.[ch]
|
||||
|
||||
device-offset-scale.path
|
||||
- Move device offset/scale handling into surface layer; large rework
|
||||
of device offset/scale. (submitted upstream)
|
||||
|
||||
push-pop-group.patch
|
||||
- Implementation of push/pop group API; depends on device-offset-scale.
|
||||
(submitted upstream)
|
||||
|
|
|
@ -84,7 +84,9 @@ CSRCS = \
|
|||
cairo-scaled-font.c \
|
||||
cairo-slope.c \
|
||||
cairo-spline.c \
|
||||
cairo-stroke-style.c \
|
||||
cairo-surface.c \
|
||||
cairo-surface-fallback.c \
|
||||
cairo-traps.c \
|
||||
cairo-unicode.c \
|
||||
cairo-wideint.c \
|
||||
|
@ -113,6 +115,10 @@ CSRCS += cairo-font-subset.c \
|
|||
EXPORTS += cairo-ps.h cairo-pdf.h
|
||||
endif
|
||||
|
||||
ifdef BUILD_CAIRO_SVG
|
||||
CSRCS += cairo-svg-surface.c
|
||||
EXPORTS += cairo-svg.h
|
||||
endif
|
||||
|
||||
ifdef MOZ_X11
|
||||
CSRCS += cairo-xlib-surface.c \
|
||||
|
|
|
@ -32,10 +32,25 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/**
|
||||
* _cairo_array_init:
|
||||
*
|
||||
* Initialize a new cairo_array object to store objects each of size
|
||||
* @element_size.
|
||||
*
|
||||
* The #cairo_array_t object provides grow-by-doubling storage. It
|
||||
* never intereprets the data passed to it, nor does it provide any
|
||||
* sort of callback mechanism for freeing resources held onto by
|
||||
* stored objects.
|
||||
*
|
||||
* When finished using the array, _cairo_array_fini() should be
|
||||
* called to free resources allocated during use of the array.
|
||||
**/
|
||||
void
|
||||
_cairo_array_init (cairo_array_t *array, int element_size)
|
||||
{
|
||||
|
@ -43,14 +58,57 @@ _cairo_array_init (cairo_array_t *array, int element_size)
|
|||
array->num_elements = 0;
|
||||
array->element_size = element_size;
|
||||
array->elements = NULL;
|
||||
|
||||
array->is_snapshot = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_init_snapshot:
|
||||
* @array: A #cairo_array_t to be initialized as a snapshot
|
||||
* @other: The #cairo_array_t from which to create the snapshot
|
||||
*
|
||||
* Initialize @array as an immutable copy of @other. It is an error to
|
||||
* call an array-modifying function (other than _cairo_array_fini) on
|
||||
* @array after calling this function.
|
||||
**/
|
||||
void
|
||||
_cairo_array_init_snapshot (cairo_array_t *array,
|
||||
const cairo_array_t *other)
|
||||
{
|
||||
array->size = other->size;
|
||||
array->num_elements = other->num_elements;
|
||||
array->element_size = other->element_size;
|
||||
array->elements = other->elements;
|
||||
|
||||
array->is_snapshot = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_fini:
|
||||
*
|
||||
* Free all resources associated with @array. After this call, @array
|
||||
* should not be used again without a subsequent call to
|
||||
* _cairo_array_init() again first.
|
||||
**/
|
||||
void
|
||||
_cairo_array_fini (cairo_array_t *array)
|
||||
{
|
||||
free (array->elements);
|
||||
if (array->is_snapshot)
|
||||
return;
|
||||
|
||||
if (array->elements) {
|
||||
free (* array->elements);
|
||||
free (array->elements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_grow_by:
|
||||
*
|
||||
* Increase the size of @array (if needed) so that there are at least
|
||||
* @additional free spaces in the array. The actual size of the array
|
||||
* is always increased by doubling as many times as necessary.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_grow_by (cairo_array_t *array, int additional)
|
||||
{
|
||||
|
@ -59,6 +117,8 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
int required_size = array->num_elements + additional;
|
||||
int new_size;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
if (required_size <= old_size)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
@ -70,8 +130,15 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
while (new_size < required_size)
|
||||
new_size = new_size * 2;
|
||||
|
||||
if (array->elements == NULL) {
|
||||
array->elements = malloc (sizeof (char *));
|
||||
if (array->elements == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
*array->elements = NULL;
|
||||
}
|
||||
|
||||
array->size = new_size;
|
||||
new_elements = realloc (array->elements,
|
||||
new_elements = realloc (*array->elements,
|
||||
array->size * array->element_size);
|
||||
|
||||
if (new_elements == NULL) {
|
||||
|
@ -79,54 +146,174 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
array->elements = new_elements;
|
||||
*array->elements = new_elements;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_truncate:
|
||||
*
|
||||
* Truncate size of the array to @num_elements if less than the
|
||||
* current size. No memory is actually freed. The stored objects
|
||||
* beyond @num_elements are simply "forgotten".
|
||||
**/
|
||||
void
|
||||
_cairo_array_truncate (cairo_array_t *array, int num_elements)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
if (num_elements < array->num_elements)
|
||||
array->num_elements = num_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_index:
|
||||
*
|
||||
* Return value: A pointer to object stored at @index. If the
|
||||
* resulting value is assigned to a pointer to an object of the same
|
||||
* element_size as initially passed to _cairo_array_init() then that
|
||||
* pointer may be used for further direct indexing with []. For
|
||||
* example:
|
||||
*
|
||||
* cairo_array_t array;
|
||||
* double *values;
|
||||
*
|
||||
* _cairo_array_init (&array, sizeof(double));
|
||||
* ... calls to _cairo_array_append() here ...
|
||||
*
|
||||
* values = _cairo_array_index (&array, 0);
|
||||
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
|
||||
* ... use values[i] here ...
|
||||
**/
|
||||
void *
|
||||
_cairo_array_index (cairo_array_t *array, int index)
|
||||
{
|
||||
/* We allow an index of 0 for the no-elements case.
|
||||
* This makes for cleaner calling code which will often look like:
|
||||
*
|
||||
* elements = _cairo_array_index (array, num_elements);
|
||||
* for (i=0; i < num_elements; i++) {
|
||||
* ... use elements[i] here ...
|
||||
* }
|
||||
*
|
||||
* which in the num_elements==0 case gets the NULL pointer here,
|
||||
* but never dereferences it.
|
||||
*/
|
||||
if (array->elements == NULL) {
|
||||
assert (index == 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (0 <= index && index < array->num_elements);
|
||||
|
||||
return (void *) &array->elements[index * array->element_size];
|
||||
return (void *) &(*array->elements)[index * array->element_size];
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_copy_element:
|
||||
*
|
||||
* Copy a single element out of the array from index @index into the
|
||||
* location pointed to by @dst.
|
||||
**/
|
||||
void
|
||||
_cairo_array_copy_element (cairo_array_t *array, int index, void *dst)
|
||||
{
|
||||
memcpy (dst, _cairo_array_index (array, index), array->element_size);
|
||||
}
|
||||
|
||||
void *
|
||||
_cairo_array_append (cairo_array_t *array,
|
||||
const void *elements, int num_elements)
|
||||
/**
|
||||
* _cairo_array_append:
|
||||
*
|
||||
* Append a single item onto the array by growing the array by at
|
||||
* least one element, then copying element_size bytes from @element
|
||||
* into the array. The address of the resulting object within the
|
||||
* array can be determined with:
|
||||
*
|
||||
* _cairo_array_index (array, _cairo_array_num_elements (array) - 1);
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful or
|
||||
* CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_append (cairo_array_t *array,
|
||||
const void *element)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
return _cairo_array_append_multiple (array, element, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_append:
|
||||
*
|
||||
* Append one or more items onto the array by growing the array by
|
||||
* @num_elements, then copying @num_elements * element_size bytes from
|
||||
* @elements into the array.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful or
|
||||
* CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_append_multiple (cairo_array_t *array,
|
||||
const void *elements,
|
||||
int num_elements)
|
||||
{
|
||||
cairo_status_t status;
|
||||
void *dest;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_allocate (array, num_elements, &dest);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
memcpy (dest, elements, num_elements * array->element_size);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_allocate:
|
||||
*
|
||||
* Allocate space at the end of the array for @num_elements additional
|
||||
* elements, providing the address of the new memory chunk in
|
||||
* @elements. This memory will be unitialized, but will be accounted
|
||||
* for in the return value of _cairo_array_num_elements().
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful or
|
||||
* CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
|
||||
* operation.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_array_allocate (cairo_array_t *array,
|
||||
int num_elements,
|
||||
void **elements)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_grow_by (array, num_elements);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return NULL;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
assert (array->num_elements + num_elements <= array->size);
|
||||
|
||||
dest = &array->elements[array->num_elements * array->element_size];
|
||||
*elements = &(*array->elements)[array->num_elements * array->element_size];
|
||||
|
||||
array->num_elements += num_elements;
|
||||
|
||||
if (elements != NULL)
|
||||
memcpy (dest, elements, num_elements * array->element_size);
|
||||
|
||||
return dest;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_num_elements:
|
||||
*
|
||||
* Return value: The number of elements stored in @array.
|
||||
**/
|
||||
int
|
||||
_cairo_array_num_elements (cairo_array_t *array)
|
||||
{
|
||||
|
@ -170,7 +357,7 @@ _cairo_user_data_array_fini (cairo_user_data_array_t *array)
|
|||
cairo_user_data_slot_t *slots;
|
||||
|
||||
num_slots = array->num_elements;
|
||||
slots = (cairo_user_data_slot_t *) array->elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].user_data != NULL && slots[i].destroy != NULL)
|
||||
slots[i].destroy (slots[i].user_data);
|
||||
|
@ -204,7 +391,7 @@ _cairo_user_data_array_get_data (cairo_user_data_array_t *array,
|
|||
return NULL;
|
||||
|
||||
num_slots = array->num_elements;
|
||||
slots = (cairo_user_data_slot_t *) array->elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].key == key)
|
||||
return slots[i].user_data;
|
||||
|
@ -235,44 +422,44 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array,
|
|||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int i, num_slots;
|
||||
cairo_user_data_slot_t *slots, *s;
|
||||
cairo_user_data_slot_t *slots, *slot, new_slot;
|
||||
|
||||
s = NULL;
|
||||
if (user_data) {
|
||||
new_slot.key = key;
|
||||
new_slot.user_data = user_data;
|
||||
new_slot.destroy = destroy;
|
||||
} else {
|
||||
new_slot.key = NULL;
|
||||
new_slot.user_data = NULL;
|
||||
new_slot.destroy = NULL;
|
||||
}
|
||||
|
||||
slot = NULL;
|
||||
num_slots = array->num_elements;
|
||||
slots = (cairo_user_data_slot_t *) array->elements;
|
||||
slots = _cairo_array_index (array, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].key == key) {
|
||||
if (slots[i].user_data != NULL && slots[i].destroy != NULL)
|
||||
slots[i].destroy (slots[i].user_data);
|
||||
s = &slots[i];
|
||||
slot = &slots[i];
|
||||
if (slot->destroy && slot->user_data)
|
||||
slot->destroy (slot->user_data);
|
||||
break;
|
||||
}
|
||||
if (user_data && slots[i].user_data == NULL) {
|
||||
s = &slots[i]; /* Have to keep searching for an exact match */
|
||||
slot = &slots[i]; /* Have to keep searching for an exact match */
|
||||
}
|
||||
}
|
||||
|
||||
if (user_data == NULL) {
|
||||
if (s != NULL) {
|
||||
s->key = NULL;
|
||||
s->user_data = NULL;
|
||||
s->destroy = NULL;
|
||||
}
|
||||
|
||||
if (slot) {
|
||||
*slot = new_slot;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
} else {
|
||||
if (s == NULL)
|
||||
s = _cairo_array_append (array, NULL, 1);
|
||||
if (s == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
s->key = key;
|
||||
s->user_data = user_data;
|
||||
s->destroy = destroy;
|
||||
}
|
||||
|
||||
status = _cairo_array_append (array, &new_slot);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,16 +38,8 @@
|
|||
#include "cairo-atsui.h"
|
||||
#include "cairoint.h"
|
||||
#include "cairo.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
/*
|
||||
* FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
|
||||
* here so we can use older SDKs.
|
||||
*/
|
||||
#ifndef FixedToFloat
|
||||
#define fixed1 ((Fixed) 0x00010000L)
|
||||
#define FixedToFloat(a) ((float)(a) / fixed1)
|
||||
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
|
||||
#endif
|
||||
typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
|
||||
typedef struct _cairo_atsui_font cairo_atsui_font_t;
|
||||
|
||||
|
@ -62,7 +54,6 @@ static cairo_status_t _cairo_atsui_font_create_scaled (cairo_font_face_t *font_f
|
|||
struct _cairo_atsui_font {
|
||||
cairo_scaled_font_t base;
|
||||
|
||||
cairo_matrix_t scale;
|
||||
ATSUStyle style;
|
||||
ATSUStyle unscaled_style;
|
||||
ATSUFontID fontID;
|
||||
|
@ -128,7 +119,7 @@ cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
|
|||
|
||||
|
||||
static CGAffineTransform
|
||||
CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
|
||||
CGAffineTransformMakeWithCairoFontScale(const cairo_matrix_t *scale)
|
||||
{
|
||||
return CGAffineTransformMake(scale->xx, scale->yx,
|
||||
scale->xy, scale->yy,
|
||||
|
@ -136,7 +127,7 @@ CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
|
|||
}
|
||||
|
||||
static ATSUStyle
|
||||
CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale)
|
||||
CreateSizedCopyOfStyle(ATSUStyle inStyle, const cairo_matrix_t *scale)
|
||||
{
|
||||
ATSUStyle style;
|
||||
OSStatus err;
|
||||
|
@ -176,17 +167,17 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
|
|||
&metrics);
|
||||
|
||||
if (err == noErr) {
|
||||
cairo_font_extents_t extents;
|
||||
cairo_font_extents_t extents;
|
||||
|
||||
extents.ascent = metrics.ascent;
|
||||
extents.descent = metrics.descent;
|
||||
extents.descent = -metrics.descent;
|
||||
extents.height = metrics.capHeight;
|
||||
extents.max_x_advance = metrics.maxAdvanceWidth;
|
||||
|
||||
// The FT backend doesn't handle max_y_advance either, so we'll ignore it for now.
|
||||
extents.max_y_advance = 0.0;
|
||||
|
||||
_cairo_scaled_font_set_metrics (&font->base, &extents);
|
||||
_cairo_scaled_font_set_metrics (&font->base, &extents);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -205,7 +196,6 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
|||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_atsui_font_t *font = NULL;
|
||||
cairo_matrix_t scale;
|
||||
OSStatus err;
|
||||
cairo_status_t status;
|
||||
|
||||
|
@ -214,8 +204,7 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
|||
_cairo_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
|
||||
&cairo_atsui_scaled_font_backend);
|
||||
|
||||
cairo_matrix_multiply(&scale, font_matrix, ctm);
|
||||
font->style = CreateSizedCopyOfStyle(style, &scale);
|
||||
font->style = CreateSizedCopyOfStyle(style, &font->base.scale);
|
||||
|
||||
Fixed theSize = FloatToFixed(1.0);
|
||||
const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
|
||||
|
@ -229,7 +218,6 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
|||
font->unscaled_style = style;
|
||||
|
||||
font->fontID = font_id;
|
||||
font->scale = scale;
|
||||
|
||||
*font_out = &font->base;
|
||||
|
||||
|
@ -550,18 +538,18 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_atsui_font_show_glyphs (void *abstract_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_atsui_font_t *font = abstract_font;
|
||||
CGContextRef myBitmapContext;
|
||||
|
@ -596,7 +584,7 @@ _cairo_atsui_font_show_glyphs (void *abstract_font,
|
|||
CGContextSetFont(myBitmapContext, cgFont);
|
||||
|
||||
CGAffineTransform textTransform =
|
||||
CGAffineTransformMakeWithCairoFontScale(&font->scale);
|
||||
CGAffineTransformMakeWithCairoFontScale(&font->base.scale);
|
||||
|
||||
textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f);
|
||||
|
||||
|
@ -615,13 +603,43 @@ _cairo_atsui_font_show_glyphs (void *abstract_font,
|
|||
CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (_cairo_surface_is_quartz (generic_surface)) {
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)generic_surface;
|
||||
if (surface->clip_region) {
|
||||
pixman_box16_t *boxes = pixman_region_rects (surface->clip_region);
|
||||
int num_boxes = pixman_region_num_rects (surface->clip_region);
|
||||
CGRect stack_rects[10];
|
||||
CGRect *rects;
|
||||
int i;
|
||||
|
||||
if (num_boxes > 10)
|
||||
rects = malloc (sizeof (CGRect) * num_boxes);
|
||||
else
|
||||
rects = stack_rects;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].origin.x = boxes[i].x1;
|
||||
rects[i].origin.y = boxes[i].y1;
|
||||
rects[i].size.width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].size.height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
CGContextClipToRects (myBitmapContext, rects, num_boxes);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free(rects);
|
||||
}
|
||||
} else {
|
||||
/* XXX: Need to get the text clipped */
|
||||
}
|
||||
|
||||
// TODO - bold and italic text
|
||||
//
|
||||
// We could draw the text using ATSUI and get bold, italics
|
||||
// etc. for free, but ATSUI does a lot of text layout work
|
||||
// that we don't really need...
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
CGGlyph theGlyph = glyphs[i].index;
|
||||
|
||||
|
@ -650,6 +668,6 @@ const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
|
|||
_cairo_atsui_font_scaled_glyph_init,
|
||||
_cairo_atsui_font_text_to_glyphs,
|
||||
NULL, /* ucs4_to_index */
|
||||
_cairo_atsui_font_show_glyphs,
|
||||
_cairo_atsui_font_old_show_glyphs,
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Christian Biesinger <cbiesinger@web.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Christian Biesinger
|
||||
* <cbiesinger@web.de>
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_BEOS_H
|
||||
#define CAIRO_BEOS_H
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#if CAIRO_HAS_BEOS_SURFACE
|
||||
|
||||
#include <View.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_beos_surface_create (BView* view);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_beos_surface_create_for_bitmap (BView* view,
|
||||
BBitmap* bmp);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_BEOS_SURFACE */
|
||||
# error Cairo was not compiled with support for the beos backend
|
||||
#endif /* CAIRO_HAS_BEOS_SURFACE */
|
||||
|
||||
#endif /* CAIRO_BEOS_H */
|
||||
|
|
@ -38,12 +38,6 @@
|
|||
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
enum _cairo_clip_mode {
|
||||
CAIRO_CLIP_MODE_PATH,
|
||||
CAIRO_CLIP_MODE_REGION,
|
||||
CAIRO_CLIP_MODE_MASK
|
||||
};
|
||||
|
||||
struct _cairo_clip_path {
|
||||
unsigned int ref_count;
|
||||
cairo_path_fixed_t path;
|
||||
|
@ -114,7 +108,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
|
|
|
@ -49,60 +49,71 @@ void
|
|||
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
{
|
||||
clip->mode = _cairo_surface_get_clip_mode (target);
|
||||
clip->region = NULL;
|
||||
|
||||
clip->surface = NULL;
|
||||
clip->surface_rect.x = 0;
|
||||
clip->surface_rect.y = 0;
|
||||
clip->surface_rect.width = 0;
|
||||
clip->surface_rect.height = 0;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
clip->region = NULL;
|
||||
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_clip_fini (cairo_clip_t *clip)
|
||||
{
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = NULL;
|
||||
|
||||
if (clip->path)
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->region)
|
||||
pixman_region_destroy (clip->region);
|
||||
clip->region = NULL;
|
||||
clip->serial = 0;
|
||||
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
{
|
||||
if (other->region) {
|
||||
clip->mode = other->mode;
|
||||
|
||||
clip->surface = cairo_surface_reference (other->surface);
|
||||
clip->surface_rect = other->surface_rect;
|
||||
|
||||
clip->serial = other->serial;
|
||||
|
||||
if (other->region == NULL) {
|
||||
clip->region = other->region;
|
||||
} else {
|
||||
clip->region = pixman_region_create ();
|
||||
pixman_region_copy (clip->region, other->region);
|
||||
}
|
||||
|
||||
cairo_surface_reference (other->surface);
|
||||
clip->surface = other->surface;
|
||||
_cairo_clip_path_reference (other->path);
|
||||
clip->path = other->path;
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_reset (cairo_clip_t *clip)
|
||||
{
|
||||
/* destroy any existing clip-region artifacts */
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = NULL;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->region)
|
||||
pixman_region_destroy (clip->region);
|
||||
clip->region = NULL;
|
||||
|
||||
if (clip->path)
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -111,6 +122,9 @@ cairo_status_t
|
|||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect path extents here. */
|
||||
}
|
||||
|
@ -148,6 +162,9 @@ cairo_status_t
|
|||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect clip path into region. */
|
||||
}
|
||||
|
@ -185,7 +202,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
|||
*/
|
||||
cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
|
@ -196,7 +213,7 @@ _cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
|||
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
|
||||
|
||||
status = _cairo_surface_composite (operator,
|
||||
status = _cairo_surface_composite (op,
|
||||
&pattern.base,
|
||||
NULL,
|
||||
dst,
|
||||
|
|
|
@ -70,3 +70,153 @@ cairo_debug_reset_static_data (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* path dumper
|
||||
*/
|
||||
|
||||
typedef struct _cairo_debug_path_dump_closure {
|
||||
unsigned int op_count;
|
||||
FILE *fp;
|
||||
} cairo_debug_path_dump_closure_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_debug_path_move_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
cairo_debug_path_dump_closure_t *fdc =
|
||||
(cairo_debug_path_dump_closure_t*) closure;
|
||||
fprintf (fdc->fp, "%d: moveto (%f, %f)\n",
|
||||
fdc->op_count++,
|
||||
_cairo_fixed_to_double(point->x),
|
||||
_cairo_fixed_to_double(point->y));
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_debug_path_line_to (void *closure,
|
||||
cairo_point_t *point)
|
||||
{
|
||||
cairo_debug_path_dump_closure_t *fdc =
|
||||
(cairo_debug_path_dump_closure_t*) closure;
|
||||
fprintf (fdc->fp, "%d: lineto (%f, %f)\n",
|
||||
fdc->op_count++,
|
||||
_cairo_fixed_to_double(point->x),
|
||||
_cairo_fixed_to_double(point->y));
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_debug_path_curve_to (void *closure,
|
||||
cairo_point_t *p0,
|
||||
cairo_point_t *p1,
|
||||
cairo_point_t *p2)
|
||||
{
|
||||
cairo_debug_path_dump_closure_t *fdc =
|
||||
(cairo_debug_path_dump_closure_t*) closure;
|
||||
fprintf (fdc->fp, "%d: curveto (%f, %f) (%f, %f) (%f, %f)\n",
|
||||
fdc->op_count++,
|
||||
_cairo_fixed_to_double(p0->x),
|
||||
_cairo_fixed_to_double(p0->y),
|
||||
_cairo_fixed_to_double(p1->x),
|
||||
_cairo_fixed_to_double(p1->y),
|
||||
_cairo_fixed_to_double(p2->x),
|
||||
_cairo_fixed_to_double(p2->y));
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_debug_path_close_path (void *closure)
|
||||
{
|
||||
cairo_debug_path_dump_closure_t *fdc =
|
||||
(cairo_debug_path_dump_closure_t*) closure;
|
||||
fprintf (fdc->fp, "%d: close\n",
|
||||
fdc->op_count++);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_debug_dump_path
|
||||
* @path: a #cairo_path_fixed_t
|
||||
* @fp: the file pointer where to dump the given path
|
||||
*
|
||||
* Dumps @path in human-readable form to @fp.
|
||||
*/
|
||||
void
|
||||
cairo_debug_dump_path (cairo_path_fixed_t *path,
|
||||
FILE *fp)
|
||||
{
|
||||
cairo_debug_path_dump_closure_t fdc;
|
||||
fdc.fp = fp;
|
||||
fdc.op_count = 0;
|
||||
|
||||
fprintf (fp, "=== path %p ===\n", path);
|
||||
_cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_debug_path_move_to,
|
||||
_cairo_debug_path_line_to,
|
||||
_cairo_debug_path_curve_to,
|
||||
_cairo_debug_path_close_path,
|
||||
&fdc);
|
||||
fprintf (fp, "======================\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* traps dumping
|
||||
*/
|
||||
|
||||
/**
|
||||
* cairo_debug_dump_traps
|
||||
* @traps: a #cairo_traps_t
|
||||
* @fp: the file pointer where to dump the traps
|
||||
*
|
||||
* Dumps @traps in human-readable form to @fp.
|
||||
*/
|
||||
void
|
||||
cairo_debug_dump_traps (cairo_traps_t *traps,
|
||||
FILE *fp)
|
||||
{
|
||||
fprintf (fp, "=== traps %p ===\n", traps);
|
||||
fprintf (fp, "extents: (%f, %f) (%f, %f)\n",
|
||||
_cairo_fixed_to_double (traps->extents.p1.x),
|
||||
_cairo_fixed_to_double (traps->extents.p1.y),
|
||||
_cairo_fixed_to_double (traps->extents.p2.x),
|
||||
_cairo_fixed_to_double (traps->extents.p2.y));
|
||||
|
||||
cairo_debug_dump_trapezoid_array (traps->traps,
|
||||
traps->num_traps,
|
||||
fp);
|
||||
|
||||
fprintf (fp, "=======================\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_debug_dump_trapezoid_array
|
||||
* @traps: a #cairo_trapezoid_t pointer
|
||||
* @num_traps: the number of trapezoids in @traps
|
||||
* @fp: the file pointer where to dump the traps
|
||||
*
|
||||
* Dumps num_traps in the @traps array in human-readable form to @fp.
|
||||
*/
|
||||
void
|
||||
cairo_debug_dump_trapezoid_array (cairo_trapezoid_t *traps,
|
||||
int num_traps,
|
||||
FILE *fp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
fprintf (fp, "% 3d: t: %f b: %f l: (%f,%f)->(%f,%f) r: (%f,%f)->(%f,%f)\n",
|
||||
i,
|
||||
_cairo_fixed_to_double (traps[i].top),
|
||||
_cairo_fixed_to_double (traps[i].bottom),
|
||||
_cairo_fixed_to_double (traps[i].left.p1.x),
|
||||
_cairo_fixed_to_double (traps[i].left.p1.y),
|
||||
_cairo_fixed_to_double (traps[i].left.p2.x),
|
||||
_cairo_fixed_to_double (traps[i].left.p2.y),
|
||||
_cairo_fixed_to_double (traps[i].right.p1.x),
|
||||
_cairo_fixed_to_double (traps[i].right.p1.y),
|
||||
_cairo_fixed_to_double (traps[i].right.p2.x),
|
||||
_cairo_fixed_to_double (traps[i].right.p2.y));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,12 +37,30 @@
|
|||
#define CAIRO_DEBUG_H
|
||||
|
||||
#include <cairo-features.h>
|
||||
#include <stdio.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
struct _cairo_path_fixed;
|
||||
struct _cairo_traps;
|
||||
struct _cairo_trapezoid;
|
||||
|
||||
void
|
||||
cairo_debug_reset_static_data (void);
|
||||
|
||||
void
|
||||
cairo_debug_dump_path (struct _cairo_path_fixed *path,
|
||||
FILE *fp);
|
||||
|
||||
void
|
||||
cairo_debug_dump_traps (struct _cairo_traps *traps,
|
||||
FILE *fp);
|
||||
|
||||
void
|
||||
cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps,
|
||||
int num_traps,
|
||||
FILE *fp);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_H */
|
||||
|
|
|
@ -0,0 +1,804 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Michael Emmel <mike.emmel@gmail.com>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <directfb.h>
|
||||
#include "cairo-directfb.h"
|
||||
#include "cairoint.h"
|
||||
|
||||
#define DFB_UNSUPPORTED -1
|
||||
#define DFB_SUPPORTED 1
|
||||
|
||||
/*
|
||||
Glyph support not working
|
||||
*/
|
||||
#define DFB_SHOW_GLYPHS 0
|
||||
/*
|
||||
Composite support not working
|
||||
*/
|
||||
#define DFB_COMPOSITE 0
|
||||
|
||||
|
||||
#if DFB_SHOW_GLYPHS
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_directfb_surface {
|
||||
cairo_surface_t base;
|
||||
cairo_format_t format;
|
||||
IDirectFB *dfb;
|
||||
IDirectFBSurface *main_surface;
|
||||
IDirectFBSurface *buffer;
|
||||
pixman_region16_t *clip;
|
||||
cairo_surface_t *buffer_image;
|
||||
void *buffer_data;
|
||||
int width;
|
||||
int height;
|
||||
} cairo_directfb_surface_t;
|
||||
|
||||
|
||||
static int
|
||||
_dfb_set_operator (cairo_operator_t operator,IDirectFBSurface *dest)
|
||||
{
|
||||
dest->SetDrawingFlags(dest,DSDRAW_BLEND);
|
||||
dest->SetPorterDuff(dest,DSPD_NONE);
|
||||
switch (operator) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
dest->SetPorterDuff(dest,DSPD_CLEAR);
|
||||
break;
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
dest->SetPorterDuff(dest,DSPD_SRC);
|
||||
break;
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
dest->SetPorterDuff(dest,DSPD_SRC_OVER);
|
||||
break;
|
||||
case CAIRO_OPERATOR_IN:
|
||||
dest->SetPorterDuff(dest,DSPD_SRC_IN);
|
||||
break;
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
dest->SetPorterDuff(dest,DSPD_SRC_OUT);
|
||||
break;
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
dest->SetPorterDuff(dest,DSPD_DST_OVER);
|
||||
break;
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
dest->SetPorterDuff(dest,DSPD_DST_IN);
|
||||
break;
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
dest->SetPorterDuff(dest,DSPD_DST_OUT);
|
||||
break;
|
||||
|
||||
/*not sure about these yet */
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return DFB_UNSUPPORTED;
|
||||
break;
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return DFB_UNSUPPORTED;
|
||||
break;
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return DFB_UNSUPPORTED;
|
||||
break;
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
dest->SetDrawingFlags(dest,DSDRAW_XOR);
|
||||
break;
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
return DFB_UNSUPPORTED;
|
||||
break;
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return DFB_UNSUPPORTED;
|
||||
break;
|
||||
default:
|
||||
return DFB_UNSUPPORTED;
|
||||
}
|
||||
return DFB_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static inline int cairo_to_directfb_format(cairo_format_t format ) {
|
||||
switch( format ) {
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
return DSPF_RGB24;
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
return DSPF_ARGB;
|
||||
case CAIRO_FORMAT_A8:
|
||||
return DSPF_A8;
|
||||
case CAIRO_FORMAT_A1:
|
||||
return DSPF_A1;
|
||||
default:
|
||||
{
|
||||
//assert(0);
|
||||
return DSPF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int directfb_to_cairo_format(DFBSurfacePixelFormat dfbformat ) {
|
||||
switch( dfbformat ) {
|
||||
case DSPF_RGB24 :
|
||||
case DSPF_RGB32 :
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
break;
|
||||
case DSPF_AiRGB :
|
||||
case DSPF_ARGB :
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
case DSPF_A8 :
|
||||
return CAIRO_FORMAT_A8;
|
||||
break;
|
||||
case DSPF_A1 :
|
||||
return CAIRO_FORMAT_A1;
|
||||
break;
|
||||
case DSPF_UNKNOWN :
|
||||
case DSPF_ARGB1555 :
|
||||
case DSPF_RGB16 :
|
||||
case DSPF_YUY2 :
|
||||
case DSPF_RGB332 :
|
||||
case DSPF_UYVY :
|
||||
case DSPF_I420 :
|
||||
case DSPF_ALUT44 :
|
||||
case DSPF_NV12 :
|
||||
case DSPF_NV16 :
|
||||
default :
|
||||
return DFB_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static IDirectFBSurface *cairo_directfb_buffer_surface_create(IDirectFB *dfb,void *data,int pitch, int format,
|
||||
int width, int height) {
|
||||
|
||||
DFBResult ret;
|
||||
IDirectFBSurface *buffer;
|
||||
DFBSurfaceDescription dsc;
|
||||
|
||||
dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
|
||||
dsc.caps = DSCAPS_NONE;
|
||||
dsc.width = width;
|
||||
dsc.height = height;
|
||||
dsc.pixelformat = format;
|
||||
if( data ) {
|
||||
dsc.flags |= DSDESC_CAPS;
|
||||
dsc.flags |= DSDESC_PREALLOCATED;
|
||||
dsc.caps = DSCAPS_NONE;
|
||||
dsc.preallocated[0].data = data;
|
||||
dsc.preallocated[0].pitch = pitch;
|
||||
dsc.preallocated[1].data = NULL;
|
||||
dsc.preallocated[1].pitch = 0;
|
||||
}
|
||||
|
||||
ret =dfb->CreateSurface (dfb, &dsc, &buffer);
|
||||
if (ret) {
|
||||
DirectFBError ("cairo_directfb_buffer_surface_create failed ", ret);
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
DFBSurfacePixelFormat dfbformat;
|
||||
int nwidth=0;
|
||||
int nheight=0;
|
||||
int npitch;
|
||||
void *ndata;
|
||||
buffer->GetSize(buffer,&nwidth,&nheight);
|
||||
buffer->GetPixelFormat(buffer,&dfbformat);
|
||||
buffer->Lock(buffer,DSLF_READ,&ndata,&npitch);
|
||||
buffer->Unlock(buffer);
|
||||
assert( ( nwidth == width) && (nheight == height));
|
||||
}
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_get_image (cairo_directfb_surface_t *surface,
|
||||
cairo_rectangle_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *rect_out,
|
||||
DFBSurfaceLockFlags flags)
|
||||
{
|
||||
int pitch;
|
||||
void *data;
|
||||
|
||||
(void)interest;
|
||||
if( surface->buffer->Lock(surface->buffer,flags,&data,&pitch) != DFB_OK )
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
/*lock the dest agianst other changes*/
|
||||
if( surface->buffer_image ) {
|
||||
if( surface->buffer_data == data ) {
|
||||
cairo_surface_reference(surface->buffer_image);
|
||||
}
|
||||
}
|
||||
|
||||
if( surface->buffer_data != data ){
|
||||
/* new off screen buffer */
|
||||
int width;
|
||||
int height;
|
||||
DFBSurfacePixelFormat dfbformat;
|
||||
/*surface moved free image if allocated */
|
||||
if( surface->buffer_image ) {
|
||||
cairo_surface_destroy (surface->buffer_image);
|
||||
surface->buffer_image=NULL;
|
||||
surface->buffer_data=NULL;
|
||||
}
|
||||
surface->buffer->Unlock(surface->buffer);
|
||||
|
||||
|
||||
surface->main_surface->GetSize(surface->main_surface,&width,&height);
|
||||
surface->main_surface->GetPixelFormat(surface->main_surface,&dfbformat);
|
||||
surface->format = directfb_to_cairo_format(dfbformat);
|
||||
|
||||
if( surface->format == DFB_UNSUPPORTED ) {
|
||||
surface->format = CAIRO_FORMAT_ARGB32;
|
||||
surface->buffer = cairo_directfb_buffer_surface_create(surface->dfb,NULL,
|
||||
0,DSPF_ARGB,width,height);
|
||||
if( !surface->buffer )
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
/*Have to flip the main surface if its double buffered to blit the buffer*/
|
||||
surface->main_surface->Flip(surface->main_surface,NULL,0);
|
||||
surface->buffer->Blit(surface->buffer,surface->main_surface,NULL,0,0);
|
||||
}else {
|
||||
surface->buffer = surface->main_surface;
|
||||
}
|
||||
|
||||
surface->width=width;
|
||||
surface->height=height;
|
||||
|
||||
if( surface->buffer->Lock(surface->buffer,flags,&data,&pitch) != DFB_OK )
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
surface->buffer_data = data;
|
||||
surface->buffer_image = cairo_image_surface_create_for_data (
|
||||
(unsigned char *)data,surface->format,width, height, pitch);
|
||||
if( surface->buffer_image == NULL ) {
|
||||
surface->buffer->Release(surface->buffer);
|
||||
surface->buffer = NULL;
|
||||
surface->buffer_data = NULL;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
#if 0
|
||||
if( surface->clip)
|
||||
_cairo_image_surface_set_clip_region (
|
||||
(cairo_image_surface_t *)surface->buffer_image,surface->clip);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rect_out) {
|
||||
rect_out->x = 0;
|
||||
rect_out->y = 0;
|
||||
rect_out->width = surface->width;
|
||||
rect_out->height = surface->height;
|
||||
}
|
||||
if( image_out )
|
||||
*image_out=(cairo_image_surface_t *)surface->buffer_image;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_directfb_surface_create_similar (void *abstract_src,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_format_t format = _cairo_format_from_content (content);
|
||||
int dfbformat;
|
||||
switch( content ) {
|
||||
case CAIRO_CONTENT_COLOR:
|
||||
dfbformat=DSPF_ARGB;
|
||||
break;
|
||||
case CAIRO_CONTENT_ALPHA:
|
||||
dfbformat=DSPF_A8;
|
||||
break;
|
||||
case CAIRO_CONTENT_COLOR_ALPHA:
|
||||
dfbformat= DSPF_ARGB;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
}
|
||||
}
|
||||
cairo_directfb_surface_t *src = abstract_src;
|
||||
IDirectFBSurface *buffer =cairo_directfb_buffer_surface_create(src->dfb,
|
||||
NULL,0,dfbformat,width,height);
|
||||
cairo_surface_t *sur =cairo_directfb_surface_create (src->dfb,buffer);
|
||||
((cairo_directfb_surface_t *)sur)->format = format;
|
||||
return sur;
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_finish (void *data ) {
|
||||
cairo_directfb_surface_t *surface=(cairo_directfb_surface_t *)data;
|
||||
if( surface->buffer_image )
|
||||
cairo_surface_destroy (surface->buffer_image);
|
||||
if (surface->clip)
|
||||
pixman_region_destroy (surface->clip);
|
||||
|
||||
if( surface->main_surface != surface->buffer ) {
|
||||
surface->main_surface->SetClip (surface->main_surface,NULL);
|
||||
surface->main_surface->Blit(surface->main_surface,surface->buffer,NULL,0,0);
|
||||
surface->buffer->Release (surface->buffer);
|
||||
surface->buffer=NULL;
|
||||
}
|
||||
#if 0 /* No don't do this */
|
||||
surface->main_surface->Flip(surface->main_surface,NULL,0);
|
||||
#endif
|
||||
surface->main_surface->Release (surface->main_surface);
|
||||
surface->main_surface=NULL;
|
||||
surface->dfb->Release(surface->dfb);
|
||||
surface->dfb=NULL;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
*image_extra = surface;
|
||||
return _cairo_directfb_surface_get_image (surface, NULL,image_out,NULL,DSLF_READ);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_directfb_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
surface->buffer->Unlock(surface->buffer);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
*image_extra = interest_rect;
|
||||
return _cairo_directfb_surface_get_image (surface, interest_rect,image_out,
|
||||
image_rect_out,DSLF_READ|DSLF_WRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
IDirectFBSurface *buffer=surface->buffer;
|
||||
buffer->Unlock(buffer);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_clone_similar (void *abstract_surface,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t **clone_out)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
cairo_directfb_surface_t *clone;
|
||||
|
||||
if (src->backend == surface->base.backend) {
|
||||
*clone_out = src;
|
||||
cairo_surface_reference (src);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
} else if (_cairo_surface_is_image (src)) {
|
||||
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
|
||||
clone = (cairo_directfb_surface_t *)
|
||||
_cairo_directfb_surface_create_similar (surface, image_src->format,
|
||||
image_src->width,
|
||||
image_src->height);
|
||||
if (!clone)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
IDirectFBSurface *tmpbuffer;
|
||||
int format = cairo_to_directfb_format(image_src->format);
|
||||
tmpbuffer =cairo_directfb_buffer_surface_create(surface->dfb,
|
||||
(void *)image_src->data,image_src->stride,format,
|
||||
image_src->width,image_src->height);
|
||||
|
||||
if (!tmpbuffer){
|
||||
cairo_surface_destroy((cairo_surface_t *)surface);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
clone->buffer->Blit(clone->buffer,tmpbuffer,NULL,0,0);
|
||||
tmpbuffer->Release(tmpbuffer);
|
||||
*clone_out = &clone->base;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#if DFB_COMPOSITE
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_directfb_surface_t *dst = abstract_dst;
|
||||
cairo_directfb_surface_t *src;
|
||||
cairo_surface_pattern_t *src_surface_pattern;
|
||||
int alpha;
|
||||
int integer_transform;
|
||||
int itx, ity;
|
||||
|
||||
cairo_directfb_surface_t *surface = abstract_dst;
|
||||
if( _dfb_set_operator(op,surface->buffer) == DFB_UNSUPPORTED )
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (src_pattern->type == CAIRO_PATTERN_SOLID ) {
|
||||
|
||||
} else if (src_pattern->type != CAIRO_PATTERN_SURFACE ||
|
||||
src_pattern->extend != CAIRO_EXTEND_NONE) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (mask_pattern) {
|
||||
/* FIXME: When we fully support RENDER style 4-channel
|
||||
* masks we need to check r/g/b != 1.0.
|
||||
*/
|
||||
if (mask_pattern->type != CAIRO_PATTERN_SOLID)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
|
||||
} else {
|
||||
alpha = 255;
|
||||
}
|
||||
|
||||
src_surface_pattern = (cairo_surface_pattern_t *)src_pattern;
|
||||
src = (cairo_directfb_surface_t *)src_surface_pattern->surface;
|
||||
|
||||
if (src->base.backend != dst->base.backend){
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
integer_transform = _cairo_matrix_is_integer_translation (&src_pattern->matrix, &itx, &ity);
|
||||
if (!integer_transform) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
surface->buffer->SetPorterDuff(surface->buffer,DSPD_NONE);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int n_rects)
|
||||
{
|
||||
int i,k;
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
IDirectFBSurface *buffer = surface->buffer;
|
||||
|
||||
if( _dfb_set_operator(op,buffer) == DFB_UNSUPPORTED ) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
buffer->SetColor(buffer,color->red_short >> 8,
|
||||
color->green_short >> 8,
|
||||
color->blue_short >> 8,
|
||||
color->alpha_short >> 8 );
|
||||
/*Not optimized not sure of the sorting on region*/
|
||||
if( surface->clip ) {
|
||||
DFBRegion region;
|
||||
int n_boxes = pixman_region_num_rects (surface->clip);
|
||||
pixman_box16_t *boxes = pixman_region_rects (surface->clip);
|
||||
for( k = 0; k < n_boxes; k++ ) {
|
||||
region.x1 = boxes[k].x1;
|
||||
region.y1 = boxes[k].y1;
|
||||
region.x2 = boxes[k].x2;
|
||||
region.y2 = boxes[k].y2;
|
||||
buffer->SetClip (buffer,®ion);
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
buffer->FillRectangle(buffer,rects[i].x,rects[i].y,
|
||||
rects[i].width,rects[i].height);
|
||||
}
|
||||
}
|
||||
buffer->SetClip (buffer, NULL);
|
||||
}else {
|
||||
buffer->SetClip (buffer, NULL);
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
buffer->FillRectangle(buffer,rects[i].x,rects[i].y,
|
||||
rects[i].width,rects[i].height);
|
||||
}
|
||||
}
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
if( region == NULL ) {
|
||||
pixman_region_destroy (surface->clip);
|
||||
surface->clip = NULL;
|
||||
}else {
|
||||
if (!surface->clip) {
|
||||
surface->clip = pixman_region_create ();
|
||||
if (!surface->clip)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
pixman_region_copy (surface->clip, region);
|
||||
}
|
||||
#if 0
|
||||
if( surface->buffer_image )
|
||||
_cairo_image_surface_set_clip_region (
|
||||
(cairo_image_surface_t *)surface->buffer_image,region);
|
||||
#endif
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
if( rectangle ) {
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = surface->width;
|
||||
rectangle->height = surface->height;
|
||||
}
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_mark_dirty_rectangle (void * abstract_surface,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
if( surface->main_surface != surface->buffer) {
|
||||
DFBRegion region;
|
||||
region.x1=x;
|
||||
region.y1=y;
|
||||
region.x2=x+width;
|
||||
region.y2=y+height;
|
||||
surface->buffer->SetClip (surface->buffer,®ion);
|
||||
surface->buffer->Blit(surface->buffer,surface->main_surface,NULL,0,0);
|
||||
surface->buffer->SetClip (surface->buffer,NULL);
|
||||
}
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_flush (void *abstract_surface)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
if( surface->main_surface != surface->buffer)
|
||||
surface->main_surface->Blit(surface->main_surface,surface->buffer,NULL,0,0);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if DFB_SHOW_GLYPHS
|
||||
static void
|
||||
_cairo_directfb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_directfb_surface_font_private_t *font_private;
|
||||
|
||||
font_private = scaled_font->surface_private;
|
||||
if (font_private)
|
||||
{
|
||||
xxx_destroy (font_private);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DFB_SHOW_GLYPHS
|
||||
static void
|
||||
_cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_directfb_surface_glyph_private_t *glyph_private;
|
||||
|
||||
glyph_private = scaled_glyph->surface_private;
|
||||
if (glyph_private)
|
||||
{
|
||||
xxx_release(glyph_private);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const cairo_surface_backend_t cairo_directfb_surface_backend = {
|
||||
_cairo_directfb_surface_create_similar,
|
||||
_cairo_directfb_surface_finish,
|
||||
_cairo_directfb_surface_acquire_source_image,
|
||||
_cairo_directfb_surface_release_source_image,
|
||||
_cairo_directfb_surface_acquire_dest_image,
|
||||
_cairo_directfb_surface_release_dest_image,
|
||||
_cairo_directfb_surface_clone_similar,
|
||||
#if DFB_COMPOSITE
|
||||
_cairo_directfb_surface_composite,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
_cairo_directfb_surface_fill_rectangles,
|
||||
NULL,/*composite_trapezoids*/
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
_cairo_directfb_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_directfb_abstract_surface_get_extents,
|
||||
#if DFB_SHOW_GLYPHS
|
||||
_cairo_directfb_surface_show_glyphs,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL, /* get_font_options */
|
||||
_cairo_directfb_surface_flush,
|
||||
_cairo_directfb_surface_mark_dirty_rectangle,
|
||||
#if DFB_SHOW_GLYPHS
|
||||
_cairo_directfb_surface_scaled_font_fini,
|
||||
_cairo_directfb_surface_scaled_glyph_fini
|
||||
#else
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
#if DFB_SHOW_GLYPHS
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
int i;
|
||||
cairo_int_status_t status;
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
if ((scaled_font->surface_backend != NULL &&
|
||||
scaled_font->surface_backend != &cairo_directfb_surface_backend) )
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (scaled_font->surface_backend == NULL) {
|
||||
scaled_font->surface_backend = &cairo_directfb_surface_backend;
|
||||
}
|
||||
/* Send all unsent glyphs to the server */
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
IDirectFBSurface *tmpbuffer;
|
||||
int x;
|
||||
int y;
|
||||
cairo_image_surface_t *glyph_img;
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
&scaled_glyph);
|
||||
glyph_img = scaled_glyph->surface;
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
/* its a space or something*/
|
||||
if( !glyph_img->data ) {
|
||||
continue;
|
||||
}
|
||||
if (scaled_glyph->surface_private == NULL ) {
|
||||
int dfbformat = cairo_to_directfb_format(glyph_img->format);
|
||||
if( dfbformat == DSPF_UNKNOWN ) {
|
||||
printf(" BAD IMAGE FORMAT[%d] cf=%d dfbf=%d data=%p \n",i,glyph_img->format,dfbformat,glyph_img->data);
|
||||
continue;
|
||||
}
|
||||
tmpbuffer = cairo_directfb_buffer_surface_create(surface->dfb,
|
||||
(void *)glyph_img->data,glyph_img->stride,dfbformat,glyph_img->width,glyph_img->height);
|
||||
/*scaled_glyph->surface_private = tmpbuffer;*/
|
||||
}else {
|
||||
tmpbuffer = (IDirectFBSurface *)scaled_glyph->surface_private;
|
||||
}
|
||||
if( !tmpbuffer ) {
|
||||
assert(0); /*something really bad happend*/
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
/* round glyph locations to the nearest pixel */
|
||||
x = (int) floor (glyphs[i].x +
|
||||
glyph_img->base.device_x_offset +
|
||||
0.5);
|
||||
y = (int) floor (glyphs[i].y +
|
||||
glyph_img->base.device_y_offset +
|
||||
0.5);
|
||||
x +=dest_x;
|
||||
y +=dest_y;
|
||||
|
||||
printf(" IMAGE FORMAT[%d] src_x=%d src_y=%d cf=%d data=%p x=%d y=%d w=%d h=%d\n",i,source_x,source_y,glyph_img->format,glyph_img->data,x,y,glyph_img->width,glyph_img->height);
|
||||
#if 0
|
||||
surface->buffer->SetColor(surface->buffer,0,0xff,0,0xff);
|
||||
surface->buffer->FillRectangle(surface->buffer,x,y,glyph_img->width,glyph_img->height);
|
||||
surface->buffer->SetColor(surface->buffer,0,0xff,0xff,0xff);
|
||||
#endif
|
||||
surface->buffer->Blit(surface->buffer,tmpbuffer,NULL,x,y);
|
||||
|
||||
}
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *dfbsurface)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = calloc(1,sizeof(cairo_directfb_surface_t));
|
||||
if( surface == NULL )
|
||||
return NULL;
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend);
|
||||
/*Reference the surface */
|
||||
dfb->AddRef(dfb);
|
||||
dfbsurface->AddRef(dfbsurface);
|
||||
surface->dfb=dfb;
|
||||
surface->main_surface = dfbsurface;
|
||||
dfbsurface->GetSize(dfbsurface,&surface->width,&surface->height);
|
||||
surface->buffer = surface->main_surface;
|
||||
surface->format = DFB_UNSUPPORTED;
|
||||
surface->clip=NULL;
|
||||
return ((cairo_surface_t *)surface);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_DIRECTFB_H
|
||||
#define CAIRO_DIRECTFB_H
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#ifdef CAIRO_HAS_DIRECTFB_SURFACE
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t * cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
||||
|
||||
#endif /*CAIRO_HAS_DIRECTFB_SURFACE*/
|
||||
#endif /*CAIRO_DIRECTFB_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -37,8 +37,6 @@
|
|||
#ifndef CAIRO_FEATURES_H
|
||||
#define CAIRO_FEATURES_H
|
||||
|
||||
#include "cairo-platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define CAIRO_BEGIN_DECLS extern "C" {
|
||||
# define CAIRO_END_DECLS }
|
||||
|
@ -47,6 +45,10 @@
|
|||
# define CAIRO_END_DECLS
|
||||
#endif
|
||||
|
||||
#ifndef cairo_public
|
||||
# define cairo_public
|
||||
#endif
|
||||
|
||||
#define CAIRO_VERSION_MAJOR 1
|
||||
#define CAIRO_VERSION_MINOR 1
|
||||
#define CAIRO_VERSION_MICRO 1
|
||||
|
@ -57,6 +59,8 @@
|
|||
|
||||
@PDF_SURFACE_FEATURE@
|
||||
|
||||
@SVG_SURFACE_FEATURE@
|
||||
|
||||
@XLIB_SURFACE_FEATURE@
|
||||
|
||||
@QUARTZ_SURFACE_FEATURE@
|
||||
|
@ -65,8 +69,12 @@
|
|||
|
||||
@WIN32_SURFACE_FEATURE@
|
||||
|
||||
@BEOS_SURFACE_FEATURE@
|
||||
|
||||
@GLITZ_SURFACE_FEATURE@
|
||||
|
||||
@DIRECTFB_SURFACE_FEATURE@
|
||||
|
||||
@FT_FONT_FEATURE@
|
||||
|
||||
@WIN32_FONT_FEATURE@
|
||||
|
|
|
@ -61,6 +61,16 @@ _cairo_font_options_init_default (cairo_font_options_t *options)
|
|||
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
options->antialias = other->antialias;
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
options->hint_style = other->hint_style;
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_create:
|
||||
*
|
||||
|
@ -107,7 +117,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
|
|||
if (!options)
|
||||
return (cairo_font_options_t *)&cairo_font_options_nil;
|
||||
|
||||
*options = *original;
|
||||
_cairo_font_options_init_copy (options, original);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-pdf.h"
|
||||
/* XXX: Eventually, we need to handle other font backends */
|
||||
#include "cairo-font-subset-private.h"
|
||||
|
||||
/* XXX: Eventually, we need to handle other font backends */
|
||||
#include "cairo-ft-private.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
|
@ -231,17 +231,31 @@ cairo_pdf_ft_font_destroy (void *abstract_font)
|
|||
free (font);
|
||||
}
|
||||
|
||||
static void *
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t *font,
|
||||
size_t length,
|
||||
unsigned char **buffer)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_array_allocate (&font->output, length, (void **) buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
|
||||
const void *data, size_t length)
|
||||
{
|
||||
void *p;
|
||||
cairo_status_t status;
|
||||
|
||||
p = _cairo_array_append (&font->output, data, length);
|
||||
if (p == NULL)
|
||||
font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_array_append_multiple (&font->output, data, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return p;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -266,12 +280,15 @@ cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
|
|||
static unsigned long
|
||||
cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
|
||||
{
|
||||
int length, aligned;
|
||||
static const char pad[4];
|
||||
int length, aligned, pad;
|
||||
unsigned char *ignored;
|
||||
|
||||
length = _cairo_array_num_elements (&font->output);
|
||||
aligned = (length + 3) & ~3;
|
||||
cairo_pdf_ft_font_write (font, pad, aligned - length);
|
||||
pad = aligned - length;
|
||||
|
||||
if (pad)
|
||||
cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
@ -305,12 +322,14 @@ static int
|
|||
cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
|
||||
size = 0;
|
||||
FT_Load_Sfnt_Table (font->face, tag, 0, NULL, &size);
|
||||
buffer = cairo_pdf_ft_font_write (font, NULL, size);
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
|
||||
/* XXX: Need to check status here. */
|
||||
FT_Load_Sfnt_Table (font->face, tag, 0, buffer, &size);
|
||||
|
||||
return 0;
|
||||
|
@ -376,6 +395,7 @@ static int
|
|||
cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long start_offset, index, size;
|
||||
TT_Header *header;
|
||||
unsigned long begin, end;
|
||||
|
@ -416,8 +436,8 @@ cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
|
|||
|
||||
font->glyphs[i].location =
|
||||
cairo_pdf_ft_font_align_output (font) - start_offset;
|
||||
buffer = cairo_pdf_ft_font_write (font, NULL, size);
|
||||
if (buffer == NULL)
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
break;
|
||||
if (size != 0) {
|
||||
FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
|
||||
|
@ -506,13 +526,16 @@ static int
|
|||
cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
|
||||
unsigned long tag)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned long entry_size;
|
||||
short *p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
entry_size = 2 * sizeof (short);
|
||||
p = cairo_pdf_ft_font_write (font, NULL, entry_size);
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, entry_size,
|
||||
(unsigned char **) &p);
|
||||
/* XXX: Need to check status here. */
|
||||
FT_Load_Sfnt_Table (font->face, TTAG_hmtx,
|
||||
font->glyphs[i].parent_index * entry_size,
|
||||
(FT_Byte *) p, &entry_size);
|
||||
|
@ -597,6 +620,9 @@ static const table_t truetype_tables[] = {
|
|||
static cairo_status_t
|
||||
cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *table_buffer;
|
||||
size_t table_buffer_length;
|
||||
unsigned short search_range, entry_selector, range_shift;
|
||||
int num_tables;
|
||||
|
||||
|
@ -616,7 +642,14 @@ cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
|
|||
cairo_pdf_ft_font_write_be16 (font, entry_selector);
|
||||
cairo_pdf_ft_font_write_be16 (font, range_shift);
|
||||
|
||||
cairo_pdf_ft_font_write (font, NULL, ARRAY_LENGTH (truetype_tables) * 16);
|
||||
/* XXX: Why are we allocating a table here and then ignoring the
|
||||
* returned buffer? This should result in garbage in the output
|
||||
* file, correct? Is this just unfinished code? -cworth. */
|
||||
table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
|
||||
status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,
|
||||
&table_buffer);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return font->status;
|
||||
}
|
||||
|
|
|
@ -401,7 +401,7 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
|
|||
|
||||
_cairo_ft_unscaled_font_init_key (&key, filename, id);
|
||||
|
||||
/* Return exsiting unscaled font if it exists in the hash table. */
|
||||
/* Return existing unscaled font if it exists in the hash table. */
|
||||
if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
|
||||
(cairo_hash_entry_t **) &unscaled))
|
||||
{
|
||||
|
@ -1890,7 +1890,7 @@ _cairo_ft_ucs4_to_index (void *abstract_font,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_ft_show_glyphs (void *abstract_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
|
|
|
@ -92,7 +92,11 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
|||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = glitz_surface_create (drawable, gformat, width, height, 0, NULL);
|
||||
surface = glitz_surface_create (drawable, gformat,
|
||||
width <= 0 ? 1 : width,
|
||||
height <= 0 ? 1 : height,
|
||||
0, NULL);
|
||||
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
@ -153,7 +157,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
rect_out->height = height;
|
||||
}
|
||||
|
||||
if (surface->format->type == GLITZ_FORMAT_TYPE_COLOR) {
|
||||
if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) {
|
||||
if (surface->format->color.red_size > 0) {
|
||||
format.bpp = 32;
|
||||
|
||||
|
@ -178,6 +182,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
format.blue_mask = 0xff;
|
||||
}
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.bpp = format.bpp;
|
||||
pf.masks.alpha_mask = format.alpha_mask;
|
||||
pf.masks.red_mask = format.red_mask;
|
||||
|
@ -201,6 +206,10 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* clear out the glitz clip; the clip affects glitz_get_pixels */
|
||||
glitz_surface_set_clip_region (surface->surface,
|
||||
0, 0, NULL, 0);
|
||||
|
||||
glitz_get_pixels (surface->surface,
|
||||
x1, y1,
|
||||
width, height,
|
||||
|
@ -209,6 +218,10 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
|
||||
glitz_buffer_destroy (buffer);
|
||||
|
||||
/* restore the clip, if any */
|
||||
surface->base.current_clip_serial = 0;
|
||||
_cairo_surface_set_clip (&surface->base, surface->base.clip);
|
||||
|
||||
image = (cairo_image_surface_t *)
|
||||
_cairo_image_surface_create_with_masks (pixels,
|
||||
&format,
|
||||
|
@ -246,6 +259,7 @@ _cairo_glitz_surface_set_image (void *abstract_surface,
|
|||
|
||||
pixman_format_get_masks (format, &pf.masks.bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.alpha_mask = am;
|
||||
pf.masks.red_mask = rm;
|
||||
pf.masks.green_mask = gm;
|
||||
|
@ -475,7 +489,7 @@ _glitz_ensure_target (glitz_surface_t *surface)
|
|||
width = glitz_surface_get_width (surface);
|
||||
height = glitz_surface_get_height (surface);
|
||||
|
||||
if (format->type != GLITZ_FORMAT_TYPE_COLOR)
|
||||
if (format->color.fourcc != GLITZ_FOURCC_RGB)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
templ.color = format->color;
|
||||
|
@ -545,10 +559,10 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
glitz_fixed16_16_t *params;
|
||||
int n_params;
|
||||
unsigned int *pixels;
|
||||
int i;
|
||||
unsigned char alpha;
|
||||
int i, n_base_params;
|
||||
glitz_buffer_t *buffer;
|
||||
static glitz_pixel_format_t format = {
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
32,
|
||||
0xff000000,
|
||||
|
@ -570,41 +584,15 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
if (gradient->n_stops < 2)
|
||||
break;
|
||||
|
||||
/* glitz doesn't support inner and outer circle with different
|
||||
center points. */
|
||||
if (pattern->type == CAIRO_PATTERN_RADIAL)
|
||||
{
|
||||
cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
|
||||
|
||||
if (grad->center0.x != grad->center1.x ||
|
||||
grad->center0.y != grad->center1.y)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))
|
||||
break;
|
||||
|
||||
if (pattern->filter != CAIRO_FILTER_BILINEAR &&
|
||||
pattern->filter != CAIRO_FILTER_GOOD &&
|
||||
pattern->filter != CAIRO_FILTER_BEST)
|
||||
break;
|
||||
if (pattern->type == CAIRO_PATTERN_RADIAL)
|
||||
n_base_params = 6;
|
||||
else
|
||||
n_base_params = 4;
|
||||
|
||||
alpha = gradient->stops[0].color.alpha * 0xff;
|
||||
for (i = 1; i < gradient->n_stops; i++)
|
||||
{
|
||||
unsigned char a;
|
||||
|
||||
a = gradient->stops[i].color.alpha * 0xff;
|
||||
if (a != alpha)
|
||||
break;
|
||||
}
|
||||
|
||||
/* we can't have color stops with different alpha as gradient color
|
||||
interpolation should be done to unpremultiplied colors. */
|
||||
if (i < gradient->n_stops)
|
||||
break;
|
||||
|
||||
n_params = gradient->n_stops * 3 + 4;
|
||||
n_params = gradient->n_stops * 3 + n_base_params;
|
||||
|
||||
data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
|
||||
sizeof (unsigned int) * gradient->n_stops);
|
||||
|
@ -636,14 +624,14 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
for (i = 0; i < gradient->n_stops; i++)
|
||||
{
|
||||
pixels[i] =
|
||||
(((int) alpha) << 24) |
|
||||
(((int) gradient->stops[i].color.red * alpha) << 16) |
|
||||
(((int) gradient->stops[i].color.green * alpha) << 8) |
|
||||
(((int) gradient->stops[i].color.blue * alpha));
|
||||
(((int) (gradient->stops[i].color.alpha >> 8)) << 24) |
|
||||
(((int) (gradient->stops[i].color.red >> 8)) << 16) |
|
||||
(((int) (gradient->stops[i].color.green >> 8)) << 8) |
|
||||
(((int) (gradient->stops[i].color.blue >> 8)));
|
||||
|
||||
params[4 + 3 * i] = gradient->stops[i].offset;
|
||||
params[5 + 3 * i] = i << 16;
|
||||
params[6 + 3 * i] = 0;
|
||||
params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
|
||||
params[n_base_params + 3 * i + 1] = i << 16;
|
||||
params[n_base_params + 3 * i + 2] = 0;
|
||||
}
|
||||
|
||||
glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
|
||||
|
@ -655,26 +643,28 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
{
|
||||
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
|
||||
|
||||
params[0] = _cairo_fixed_from_double (grad->point0.x);
|
||||
params[1] = _cairo_fixed_from_double (grad->point0.y);
|
||||
params[2] = _cairo_fixed_from_double (grad->point1.x);
|
||||
params[3] = _cairo_fixed_from_double (grad->point1.y);
|
||||
params[0] = grad->gradient.p1.x;
|
||||
params[1] = grad->gradient.p1.y;
|
||||
params[2] = grad->gradient.p2.x;
|
||||
params[3] = grad->gradient.p2.y;
|
||||
attr->filter = GLITZ_FILTER_LINEAR_GRADIENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
|
||||
|
||||
params[0] = _cairo_fixed_from_double (grad->center0.x);
|
||||
params[1] = _cairo_fixed_from_double (grad->center0.y);
|
||||
params[2] = _cairo_fixed_from_double (grad->radius0);
|
||||
params[3] = _cairo_fixed_from_double (grad->radius1);
|
||||
params[0] = grad->gradient.inner.x;
|
||||
params[1] = grad->gradient.inner.y;
|
||||
params[2] = grad->gradient.inner.radius;
|
||||
params[3] = grad->gradient.outer.x;
|
||||
params[4] = grad->gradient.outer.y;
|
||||
params[5] = grad->gradient.outer.radius;
|
||||
attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;
|
||||
}
|
||||
|
||||
switch (pattern->extend) {
|
||||
case CAIRO_EXTEND_NONE:
|
||||
attr->fill = GLITZ_FILL_NEAREST;
|
||||
attr->fill = GLITZ_FILL_TRANSPARENT;
|
||||
break;
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
attr->fill = GLITZ_FILL_REPEAT;
|
||||
|
@ -682,6 +672,9 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
case CAIRO_EXTEND_REFLECT:
|
||||
attr->fill = GLITZ_FILL_REFLECT;
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
attr->fill = GLITZ_FILL_NEAREST;
|
||||
break;
|
||||
}
|
||||
|
||||
attr->params = params;
|
||||
|
@ -717,6 +710,10 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
case CAIRO_EXTEND_REFLECT:
|
||||
attr->fill = GLITZ_FILL_REFLECT;
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
default:
|
||||
attr->fill = GLITZ_FILL_NEAREST;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (attr->base.filter) {
|
||||
|
@ -1008,6 +1005,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
cairo_int_status_t status;
|
||||
unsigned short alpha;
|
||||
|
||||
if (antialias != CAIRO_ANTIALIAS_DEFAULT &&
|
||||
antialias != CAIRO_ANTIALIAS_GRAY)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (dst->base.status)
|
||||
return dst->base.status;
|
||||
|
||||
|
@ -1818,6 +1819,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
|||
|
||||
pixman_format_get_masks (format, &pf.masks.bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.alpha_mask = am;
|
||||
pf.masks.red_mask = rm;
|
||||
pf.masks.green_mask = gm;
|
||||
|
@ -1856,18 +1858,18 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
|||
#define N_STACK_BUF 256
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_glitz_surface_attributes_t attributes;
|
||||
cairo_glitz_surface_glyph_private_t *glyph_private;
|
||||
|
@ -2108,6 +2110,16 @@ UNLOCK:
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_glitz_surface_flush (void *abstract_surface)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
||||
glitz_surface_flush (surface->surface);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||
_cairo_glitz_surface_create_similar,
|
||||
_cairo_glitz_surface_finish,
|
||||
|
@ -2124,10 +2136,9 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
|||
_cairo_glitz_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_glitz_surface_get_extents,
|
||||
_cairo_glitz_surface_show_glyphs,
|
||||
NULL, /* fill_path */
|
||||
_cairo_glitz_surface_old_show_glyphs,
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
_cairo_glitz_surface_flush,
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
_cairo_glitz_surface_scaled_font_fini,
|
||||
_cairo_glitz_surface_scaled_glyph_fini
|
||||
|
|
|
@ -39,23 +39,15 @@
|
|||
#include "cairo-clip-private.h"
|
||||
|
||||
struct _cairo_gstate {
|
||||
cairo_operator_t operator;
|
||||
cairo_operator_t op;
|
||||
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
|
||||
/* stroke style */
|
||||
double line_width;
|
||||
cairo_line_cap_t line_cap;
|
||||
cairo_line_join_t line_join;
|
||||
double miter_limit;
|
||||
cairo_stroke_style_t stroke_style;
|
||||
|
||||
cairo_fill_rule_t fill_rule;
|
||||
|
||||
double *dash;
|
||||
int num_dashes;
|
||||
double dash_offset;
|
||||
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */
|
||||
cairo_matrix_t font_matrix;
|
||||
|
@ -63,14 +55,14 @@ struct _cairo_gstate {
|
|||
|
||||
cairo_clip_t clip;
|
||||
|
||||
cairo_surface_t *target;
|
||||
cairo_surface_t *target; /* The target to which all rendering is directed */
|
||||
cairo_surface_t *parent_target; /* The previous target which was receiving rendering */
|
||||
cairo_surface_t *original_target; /* The original target the initial gstate was created with */
|
||||
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */
|
||||
|
||||
cairo_pen_t pen_regular;
|
||||
|
||||
cairo_pattern_t *source;
|
||||
|
||||
struct _cairo_gstate *next;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -51,7 +51,7 @@ _cairo_format_bpp (cairo_format_t format)
|
|||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
cairo_format_t format)
|
||||
{
|
||||
|
@ -80,6 +80,46 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
|||
return &surface->base;
|
||||
}
|
||||
|
||||
/* Try to recover a cairo_format_t from a pixman_format
|
||||
* by looking at the bpp and masks values. */
|
||||
static cairo_format_t
|
||||
_cairo_format_from_pixman_format (pixman_format_t *pixman_format)
|
||||
{
|
||||
int bpp, am, rm, gm, bm;
|
||||
|
||||
pixman_format_get_masks (pixman_format, &bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
if (bpp == 32 &&
|
||||
am == 0xff000000 &&
|
||||
rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
|
||||
if (bpp == 32 &&
|
||||
am == 0x0 &&
|
||||
rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
|
||||
if (bpp == 8 &&
|
||||
am == 0xff &&
|
||||
rm == 0x0 &&
|
||||
gm == 0x0 &&
|
||||
bm == 0x0)
|
||||
return CAIRO_FORMAT_A8;
|
||||
|
||||
if (bpp == 1 &&
|
||||
am == 0x1 &&
|
||||
rm == 0x0 &&
|
||||
gm == 0x0 &&
|
||||
bm == 0x0)
|
||||
return CAIRO_FORMAT_A1;
|
||||
|
||||
return (cairo_format_t) -1;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_with_masks (unsigned char *data,
|
||||
cairo_format_masks_t *format,
|
||||
|
@ -90,6 +130,7 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
|
|||
cairo_surface_t *surface;
|
||||
pixman_format_t *pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
cairo_format_t cairo_format;
|
||||
|
||||
pixman_format = pixman_format_create_masks (format->bpp,
|
||||
format->alpha_mask,
|
||||
|
@ -102,6 +143,8 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
|
|||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
cairo_format = _cairo_format_from_pixman_format (pixman_format);
|
||||
|
||||
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
|
||||
width, height, format->bpp, stride);
|
||||
|
||||
|
@ -113,7 +156,7 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
|
|||
}
|
||||
|
||||
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
|
||||
(cairo_format_t)-1);
|
||||
cairo_format);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@ -341,7 +384,7 @@ _cairo_image_surface_create_similar (void *abstract_src,
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_image_abstract_surface_finish (void *abstract_surface)
|
||||
_cairo_image_surface_finish (void *abstract_surface)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -433,17 +476,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
|
|||
{
|
||||
pixman_transform_t pixman_transform;
|
||||
|
||||
pixman_transform.matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
|
||||
pixman_transform.matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
|
||||
pixman_transform.matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
|
||||
|
||||
pixman_transform.matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
|
||||
pixman_transform.matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
|
||||
pixman_transform.matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
pixman_transform.matrix[2][0] = 0;
|
||||
pixman_transform.matrix[2][1] = 0;
|
||||
pixman_transform.matrix[2][2] = _cairo_fixed_from_double (1);
|
||||
_cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
|
||||
|
||||
pixman_image_set_transform (surface->pixman_image, &pixman_transform);
|
||||
|
||||
|
@ -480,14 +513,6 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_image_surface_set_repeat (cairo_image_surface_t *surface, int repeat)
|
||||
{
|
||||
pixman_image_set_repeat (surface->pixman_image, repeat);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
|
||||
cairo_surface_attributes_t *attributes)
|
||||
|
@ -500,14 +525,16 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
|
|||
|
||||
switch (attributes->extend) {
|
||||
case CAIRO_EXTEND_NONE:
|
||||
_cairo_image_surface_set_repeat (surface, 0);
|
||||
pixman_image_set_repeat (surface->pixman_image, PIXMAN_REPEAT_NONE);
|
||||
break;
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
_cairo_image_surface_set_repeat (surface, 1);
|
||||
pixman_image_set_repeat (surface->pixman_image, PIXMAN_REPEAT_NORMAL);
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
/* XXX: Obviously wrong. */
|
||||
_cairo_image_surface_set_repeat (surface, 1);
|
||||
pixman_image_set_repeat (surface->pixman_image, PIXMAN_REPEAT_REFLECT);
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
pixman_image_set_repeat (surface->pixman_image, PIXMAN_REPEAT_PAD);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -522,9 +549,9 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
|
|||
* things in pixman I think).
|
||||
*/
|
||||
static pixman_operator_t
|
||||
_pixman_operator (cairo_operator_t operator)
|
||||
_pixman_operator (cairo_operator_t op)
|
||||
{
|
||||
switch (operator) {
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return PIXMAN_OPERATOR_CLEAR;
|
||||
|
||||
|
@ -562,7 +589,7 @@ _pixman_operator (cairo_operator_t operator)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_composite (cairo_operator_t operator,
|
||||
_cairo_image_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -602,7 +629,7 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
if (status)
|
||||
goto CLEANUP_SURFACES;
|
||||
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask->pixman_image,
|
||||
dst->pixman_image,
|
||||
|
@ -615,7 +642,7 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
}
|
||||
else
|
||||
{
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
NULL,
|
||||
dst->pixman_image,
|
||||
|
@ -626,9 +653,7 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
width, height);
|
||||
}
|
||||
|
||||
if (!_cairo_operator_bounded (operator) ||
|
||||
operator == CAIRO_OPERATOR_SOURCE ||
|
||||
operator == CAIRO_OPERATOR_CLEAR)
|
||||
if (!_cairo_operator_bounded_by_source (op))
|
||||
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
|
||||
&src_attr, src->width, src->height,
|
||||
mask ? &mask_attr : NULL,
|
||||
|
@ -649,7 +674,7 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -664,7 +689,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
|||
pixman_color.alpha = color->alpha_short;
|
||||
|
||||
/* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
|
||||
pixman_fill_rectangles (_pixman_operator(operator), surface->pixman_image,
|
||||
pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image,
|
||||
&pixman_color, (pixman_rectangle_t *) rects, num_rects);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -685,7 +710,7 @@ _cairo_image_surface_is_alpha_only (cairo_image_surface_t *surface)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
_cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -721,7 +746,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
* falling through to the general case when the surface is clipped
|
||||
* since libpixman would have to generate an intermediate mask anyways.
|
||||
*/
|
||||
if (operator == CAIRO_OPERATOR_ADD &&
|
||||
if (op == CAIRO_OPERATOR_ADD &&
|
||||
_cairo_pattern_is_opaque_solid (pattern) &&
|
||||
_cairo_image_surface_is_alpha_only (dst) &&
|
||||
!dst->has_clip &&
|
||||
|
@ -781,7 +806,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
pixman_add_trapezoids (mask, - dst_x, - dst_y,
|
||||
(pixman_trapezoid_t *) traps, num_traps);
|
||||
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask,
|
||||
dst->pixman_image,
|
||||
|
@ -791,7 +816,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
if (!_cairo_operator_bounded (operator))
|
||||
if (!_cairo_operator_bounded_by_mask (op))
|
||||
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
|
||||
&attributes, src->width, src->height,
|
||||
width, height,
|
||||
|
@ -810,18 +835,11 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_abstract_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
|
||||
|
||||
return _cairo_image_surface_set_clip_region (surface, region);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
pixman_image_set_clip_region (surface->pixman_image, region);
|
||||
|
||||
surface->has_clip = region != NULL;
|
||||
|
@ -830,9 +848,11 @@ _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_get_extents (cairo_image_surface_t *surface,
|
||||
_cairo_image_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = surface->width;
|
||||
|
@ -841,15 +861,6 @@ _cairo_image_surface_get_extents (cairo_image_surface_t *surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_abstract_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_image_surface_get_extents (surface, rectangle);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_is_image:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
@ -859,14 +870,14 @@ _cairo_image_abstract_surface_get_extents (void *abstract_surface,
|
|||
* Return value: TRUE if the surface is an image surface
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_image (cairo_surface_t *surface)
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface)
|
||||
{
|
||||
return surface->backend == &cairo_image_surface_backend;
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t cairo_image_surface_backend = {
|
||||
_cairo_image_surface_create_similar,
|
||||
_cairo_image_abstract_surface_finish,
|
||||
_cairo_image_surface_finish,
|
||||
_cairo_image_surface_acquire_source_image,
|
||||
_cairo_image_surface_release_source_image,
|
||||
_cairo_image_surface_acquire_dest_image,
|
||||
|
@ -877,8 +888,8 @@ const cairo_surface_backend_t cairo_image_surface_backend = {
|
|||
_cairo_image_surface_composite_trapezoids,
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
_cairo_image_abstract_surface_set_clip_region,
|
||||
_cairo_image_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_image_abstract_surface_get_extents,
|
||||
NULL /* show_glyphs */
|
||||
_cairo_image_surface_get_extents,
|
||||
NULL /* old_show_glyphs */
|
||||
};
|
||||
|
|
|
@ -700,3 +700,20 @@ _cairo_matrix_transformed_circle_major_axis (cairo_matrix_t *matrix, double radi
|
|||
* double min = radius * sqrt (f - sqrt (g*g+h*h));
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
|
||||
pixman_transform_t *pixman_transform)
|
||||
{
|
||||
pixman_transform->matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
|
||||
pixman_transform->matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
|
||||
pixman_transform->matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
|
||||
|
||||
pixman_transform->matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
|
||||
pixman_transform->matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
|
||||
pixman_transform->matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
pixman_transform->matrix[2][0] = 0;
|
||||
pixman_transform->matrix[2][1] = 0;
|
||||
pixman_transform->matrix[2][2] = _cairo_fixed_from_double (1);
|
||||
}
|
||||
|
|
|
@ -40,59 +40,66 @@
|
|||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
typedef enum {
|
||||
CAIRO_COMMAND_COMPOSITE,
|
||||
CAIRO_COMMAND_FILL_RECTANGLES,
|
||||
CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS,
|
||||
CAIRO_COMMAND_SET_CLIP_REGION,
|
||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH,
|
||||
/* The 5 basic drawing operations. */
|
||||
CAIRO_COMMAND_PAINT,
|
||||
CAIRO_COMMAND_MASK,
|
||||
CAIRO_COMMAND_STROKE,
|
||||
CAIRO_COMMAND_FILL,
|
||||
CAIRO_COMMAND_SHOW_GLYPHS,
|
||||
CAIRO_COMMAND_FILL_PATH
|
||||
|
||||
/* Other junk. For most of these, we should be able to assert that
|
||||
* they never get called except as part of fallbacks for the 5
|
||||
* basic drawing operations (which we implement already so the
|
||||
* fallbacks should never get triggered). So the plan is to
|
||||
* eliminate as many of these as possible. */
|
||||
|
||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH,
|
||||
|
||||
} cairo_command_type_t;
|
||||
|
||||
typedef struct _cairo_command_composite {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t operator;
|
||||
cairo_pattern_union_t src_pattern;
|
||||
cairo_pattern_union_t mask_pattern;
|
||||
cairo_pattern_t *mask_pattern_pointer;
|
||||
int src_x;
|
||||
int src_y;
|
||||
int mask_x;
|
||||
int mask_y;
|
||||
int dst_x;
|
||||
int dst_y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
} cairo_command_composite_t;
|
||||
typedef struct _cairo_command_paint {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
} cairo_command_paint_t;
|
||||
|
||||
typedef struct _cairo_command_fill_rectangles {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t operator;
|
||||
cairo_color_t color;
|
||||
cairo_rectangle_t *rects;
|
||||
int num_rects;
|
||||
} cairo_command_fill_rectangles_t;
|
||||
typedef struct _cairo_command_mask {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_pattern_union_t mask;
|
||||
} cairo_command_mask_t;
|
||||
|
||||
typedef struct _cairo_command_composite_trapezoids {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t operator;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_antialias_t antialias;
|
||||
int x_src;
|
||||
int y_src;
|
||||
int x_dst;
|
||||
int y_dst;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
cairo_trapezoid_t *traps;
|
||||
int num_traps;
|
||||
} cairo_command_composite_trapezoids_t;
|
||||
typedef struct _cairo_command_stroke {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_stroke_style_t style;
|
||||
cairo_matrix_t ctm;
|
||||
cairo_matrix_t ctm_inverse;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_stroke_t;
|
||||
|
||||
typedef struct _cairo_command_set_clip_region {
|
||||
cairo_command_type_t type;
|
||||
pixman_region16_t *region;
|
||||
unsigned int serial;
|
||||
} cairo_command_set_clip_region_t;
|
||||
typedef struct _cairo_command_fill {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_fill_t;
|
||||
|
||||
typedef struct _cairo_command_show_glyphs {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t op;
|
||||
cairo_pattern_union_t source;
|
||||
cairo_glyph_t *glyphs;
|
||||
int num_glyphs;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
} cairo_command_show_glyphs_t;
|
||||
|
||||
typedef struct _cairo_command_intersect_clip_path {
|
||||
cairo_command_type_t type;
|
||||
|
@ -103,53 +110,41 @@ typedef struct _cairo_command_intersect_clip_path {
|
|||
cairo_antialias_t antialias;
|
||||
} cairo_command_intersect_clip_path_t;
|
||||
|
||||
typedef struct _cairo_command_show_glyphs {
|
||||
cairo_command_type_t type;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
cairo_operator_t operator;
|
||||
cairo_pattern_union_t pattern;
|
||||
int source_x;
|
||||
int source_y;
|
||||
int dest_x;
|
||||
int dest_y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
cairo_glyph_t *glyphs;
|
||||
int num_glyphs;
|
||||
} cairo_command_show_glyphs_t;
|
||||
|
||||
typedef struct _cairo_command_fill_path {
|
||||
cairo_command_type_t type;
|
||||
cairo_operator_t operator;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
} cairo_command_fill_path_t;
|
||||
|
||||
typedef union _cairo_command {
|
||||
cairo_command_type_t type;
|
||||
cairo_command_composite_t composite;
|
||||
cairo_command_fill_rectangles_t fill_rectangles;
|
||||
cairo_command_composite_trapezoids_t composite_trapezoids;
|
||||
cairo_command_set_clip_region_t set_clip_region;
|
||||
cairo_command_intersect_clip_path_t intersect_clip_path;
|
||||
|
||||
/* The 5 basic drawing operations. */
|
||||
cairo_command_paint_t paint;
|
||||
cairo_command_mask_t mask;
|
||||
cairo_command_stroke_t stroke;
|
||||
cairo_command_fill_t fill;
|
||||
cairo_command_show_glyphs_t show_glyphs;
|
||||
cairo_command_fill_path_t fill_path;
|
||||
|
||||
/* The other junk. */
|
||||
cairo_command_intersect_clip_path_t intersect_clip_path;
|
||||
} cairo_command_t;
|
||||
|
||||
typedef struct _cairo_meta_surface {
|
||||
cairo_surface_t base;
|
||||
double width, height;
|
||||
|
||||
/* A meta-surface is logically unbounded, but when used as a
|
||||
* source we need to render it to an image, so we need a size at
|
||||
* which to create that image. */
|
||||
int width_pixels;
|
||||
int height_pixels;
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
} cairo_meta_surface_t;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_meta_surface_create (double width, double height);
|
||||
_cairo_meta_surface_create (int width_pixels, int height_pixels);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||
|
||||
#endif /* CAIRO_META_SURFACE_H */
|
||||
|
|
|
@ -31,16 +31,36 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
/* A meta surface is a surface that records all drawing operations at
|
||||
* the highest level of the surface backend interface, (that is, the
|
||||
* level of paint, mask, stroke, fill, and show_glyphs). The meta
|
||||
* surface can then be "replayed" against any target surface with:
|
||||
*
|
||||
* _cairo_meta_surface_replay (meta, target);
|
||||
*
|
||||
* after which the results in target will be identical to the results
|
||||
* that would have been obtained if the original operations applied to
|
||||
* the meta surface had instead been applied to the target surface.
|
||||
*
|
||||
* The recording phase of the meta surface is careful to snapshot all
|
||||
* necessary objects (paths, patterns, etc.), in order to acheive
|
||||
* accurate replay. The efficiency of the meta surface could be
|
||||
* improved by improving the implementation of snapshot for the
|
||||
* various objects. For example, it would be nice to have a
|
||||
* copy-on-write implementation for _cairo_surface_snapshot.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_meta_surface_create (double width, double height)
|
||||
_cairo_meta_surface_create (int width_pixels, int height_pixels)
|
||||
{
|
||||
cairo_meta_surface_t *meta;
|
||||
|
||||
|
@ -50,10 +70,13 @@ _cairo_meta_surface_create (double width, double height)
|
|||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
meta->width = width;
|
||||
meta->height = height;
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
|
||||
meta->width_pixels = width_pixels;
|
||||
meta->height_pixels = height_pixels;
|
||||
|
||||
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
||||
meta->commands_owner = NULL;
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
|
@ -75,45 +98,54 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
|||
cairo_command_t **elements;
|
||||
int i, num_elements;
|
||||
|
||||
if (meta->commands_owner) {
|
||||
cairo_surface_destroy (meta->commands_owner);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
num_elements = meta->commands.num_elements;
|
||||
elements = (cairo_command_t **) meta->commands.elements;
|
||||
elements = _cairo_array_index (&meta->commands, 0);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
command = elements[i];
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_COMPOSITE:
|
||||
_cairo_pattern_fini (&command->composite.src_pattern.base);
|
||||
if (command->composite.mask_pattern_pointer)
|
||||
_cairo_pattern_fini (command->composite.mask_pattern_pointer);
|
||||
|
||||
/* 5 basic drawing operations */
|
||||
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
_cairo_pattern_fini (&command->paint.source.base);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL_RECTANGLES:
|
||||
free (command->fill_rectangles.rects);
|
||||
case CAIRO_COMMAND_MASK:
|
||||
_cairo_pattern_fini (&command->mask.source.base);
|
||||
_cairo_pattern_fini (&command->mask.mask.base);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_STROKE:
|
||||
_cairo_pattern_fini (&command->stroke.source.base);
|
||||
_cairo_path_fixed_fini (&command->stroke.path);
|
||||
_cairo_stroke_style_fini (&command->stroke.style);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
|
||||
_cairo_pattern_fini (&command->composite_trapezoids.pattern.base);
|
||||
free (command->composite_trapezoids.traps);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
if (command->intersect_clip_path.path_pointer)
|
||||
_cairo_path_fixed_fini (&command->intersect_clip_path.path);
|
||||
case CAIRO_COMMAND_FILL:
|
||||
_cairo_pattern_fini (&command->fill.source.base);
|
||||
_cairo_path_fixed_fini (&command->fill.path);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
cairo_scaled_font_destroy (command->show_glyphs.scaled_font);
|
||||
_cairo_pattern_fini (&command->show_glyphs.pattern.base);
|
||||
_cairo_pattern_fini (&command->show_glyphs.source.base);
|
||||
free (command->show_glyphs.glyphs);
|
||||
cairo_scaled_font_destroy (command->show_glyphs.scaled_font);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL_PATH:
|
||||
_cairo_pattern_fini (&command->fill_path.pattern.base);
|
||||
_cairo_path_fixed_fini (&command->fill_path.path);
|
||||
/* Other junk. */
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
if (command->intersect_clip_path.path_pointer)
|
||||
_cairo_path_fixed_fini (&command->intersect_clip_path.path);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
|
@ -127,142 +159,322 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_surface,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
static cairo_status_t
|
||||
_cairo_meta_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_composite_t *command;
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
|
||||
command = malloc (sizeof (cairo_command_composite_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
surface->width_pixels,
|
||||
surface->height_pixels);
|
||||
|
||||
command->type = CAIRO_COMMAND_COMPOSITE;
|
||||
command->operator = operator;
|
||||
_cairo_pattern_init_copy (&command->src_pattern.base, src_pattern);
|
||||
if (mask_pattern) {
|
||||
_cairo_pattern_init_copy (&command->mask_pattern.base, mask_pattern);
|
||||
command->mask_pattern_pointer = &command->mask_pattern.base;
|
||||
} else {
|
||||
command->mask_pattern_pointer = NULL;
|
||||
status = _cairo_meta_surface_replay (&surface->base, image);
|
||||
if (status) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
|
||||
command->src_x = src_x;
|
||||
command->src_y = src_y;
|
||||
command->mask_x = mask_x;
|
||||
command->mask_y = mask_y;
|
||||
command->dst_x = dst_x;
|
||||
command->dst_y = dst_y;
|
||||
command->width = width;
|
||||
command->height = height;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
_cairo_pattern_fini (&command->src_pattern.base);
|
||||
_cairo_pattern_fini (command->mask_pattern_pointer);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_meta_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other)
|
||||
{
|
||||
_cairo_pattern_init_copy (pattern, other);
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern =
|
||||
(cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_t *surface = surface_pattern->surface;
|
||||
|
||||
surface_pattern->surface = _cairo_surface_snapshot (surface);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
if (surface_pattern->surface->status)
|
||||
return surface_pattern->surface->status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_meta_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_fill_rectangles_t *command;
|
||||
cairo_command_paint_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_fill_rectangles_t));
|
||||
command = malloc (sizeof (cairo_command_paint_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_FILL_RECTANGLES;
|
||||
command->operator = operator;
|
||||
command->color = *color;
|
||||
command->type = CAIRO_COMMAND_PAINT;
|
||||
command->op = op;
|
||||
|
||||
command->rects = malloc (sizeof (cairo_rectangle_t) * num_rects);
|
||||
if (command->rects == NULL) {
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy (command->rects, rects, sizeof (cairo_rectangle_t) * num_rects);
|
||||
|
||||
command->num_rects = num_rects;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
free (command->rects);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
status = _init_pattern_with_snapshot (&command->source.base, source);
|
||||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status)
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
cairo_antialias_t antialias,
|
||||
int x_src,
|
||||
int y_src,
|
||||
int x_dst,
|
||||
int y_dst,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
_cairo_meta_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_composite_trapezoids_t *command;
|
||||
cairo_command_mask_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_composite_trapezoids_t));
|
||||
command = malloc (sizeof (cairo_command_mask_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS;
|
||||
command->operator = operator;
|
||||
_cairo_pattern_init_copy (&command->pattern.base, pattern);
|
||||
command->type = CAIRO_COMMAND_MASK;
|
||||
command->op = op;
|
||||
|
||||
status = _init_pattern_with_snapshot (&command->source.base, source);
|
||||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
status = _init_pattern_with_snapshot (&command->mask.base, mask);
|
||||
if (status)
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status)
|
||||
goto CLEANUP_MASK;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_MASK:
|
||||
_cairo_pattern_fini (&command->mask.base);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_stroke_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_stroke_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_STROKE;
|
||||
command->op = op;
|
||||
|
||||
status = _init_pattern_with_snapshot (&command->source.base, source);
|
||||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
status = _cairo_path_fixed_init_copy (&command->path, path);
|
||||
if (status)
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
status = _cairo_stroke_style_init_copy (&command->style, style);
|
||||
if (status)
|
||||
goto CLEANUP_PATH;
|
||||
|
||||
command->ctm = *ctm;
|
||||
command->ctm_inverse = *ctm_inverse;
|
||||
command->tolerance = tolerance;
|
||||
command->antialias = antialias;
|
||||
command->x_src = x_src;
|
||||
command->y_src = y_src;
|
||||
command->x_dst = x_dst;
|
||||
command->y_dst = y_dst;
|
||||
command->width = width;
|
||||
command->height = height;
|
||||
|
||||
command->traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
|
||||
if (command->traps == NULL) {
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy (command->traps, traps, sizeof (cairo_trapezoid_t) * num_traps);
|
||||
|
||||
command->num_traps = num_traps;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command->traps);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status)
|
||||
goto CLEANUP_STYLE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_STYLE:
|
||||
_cairo_stroke_style_fini (&command->style);
|
||||
CLEANUP_PATH:
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_fill_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_fill_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_FILL;
|
||||
command->op = op;
|
||||
|
||||
status = _init_pattern_with_snapshot (&command->source.base, source);
|
||||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
status = _cairo_path_fixed_init_copy (&command->path, path);
|
||||
if (status)
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
command->fill_rule = fill_rule;
|
||||
command->tolerance = tolerance;
|
||||
command->antialias = antialias;
|
||||
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status)
|
||||
goto CLEANUP_PATH;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_PATH:
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_show_glyphs_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_show_glyphs_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_SHOW_GLYPHS;
|
||||
command->op = op;
|
||||
|
||||
status = _init_pattern_with_snapshot (&command->source.base, source);
|
||||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
|
||||
if (command->glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
||||
|
||||
command->num_glyphs = num_glyphs;
|
||||
|
||||
command->scaled_font = cairo_scaled_font_reference (scaled_font);
|
||||
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status)
|
||||
goto CLEANUP_SCALED_FONT;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_SCALED_FONT:
|
||||
cairo_scaled_font_destroy (command->scaled_font);
|
||||
free (command->glyphs);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_meta_surface_snapshot
|
||||
* @surface: a #cairo_surface_t which must be a meta surface
|
||||
*
|
||||
* Make an immutable copy of @surface. It is an error to call a
|
||||
* surface-modifying function on the result of this function.
|
||||
*
|
||||
* The caller owns the return value and should call
|
||||
* cairo_surface_destroy when finished with it. This function will not
|
||||
* return NULL, but will return a nil surface instead.
|
||||
*
|
||||
* Return value: The snapshot surface.
|
||||
**/
|
||||
static cairo_surface_t *
|
||||
_cairo_meta_surface_snapshot (void *abstract_other)
|
||||
{
|
||||
cairo_meta_surface_t *other = abstract_other;
|
||||
cairo_meta_surface_t *meta;
|
||||
|
||||
meta = malloc (sizeof (cairo_meta_surface_t));
|
||||
if (meta == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
meta->base.is_snapshot = TRUE;
|
||||
|
||||
meta->width_pixels = other->width_pixels;
|
||||
meta->height_pixels = other->height_pixels;
|
||||
|
||||
_cairo_array_init_snapshot (&meta->commands, &other->commands);
|
||||
meta->commands_owner = cairo_surface_reference (&other->base);
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -296,146 +508,88 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
|||
command->tolerance = tolerance;
|
||||
command->antialias = antialias;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
status = _cairo_array_append (&meta->commands, &command);
|
||||
if (status) {
|
||||
if (path)
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* A meta-surface is logically unbounded, but when it is used as a
|
||||
* source, the drawing code can optimize based on the extents of the
|
||||
* surface.
|
||||
*
|
||||
* XXX: The optimization being attempted here would only actually work
|
||||
* if the meta-surface kept track of its extents as commands were
|
||||
* added to it.
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
|
||||
/* Currently this is used for getting the extents of the surface
|
||||
* before calling cairo_paint(). This is the only this that
|
||||
* requires the meta surface to have an explicit size. If paint
|
||||
* was just a backend function, this would not be necessary. */
|
||||
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = meta->width;
|
||||
rectangle->height = meta->height;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_show_glyphs_t *command;
|
||||
|
||||
command = malloc (sizeof (cairo_command_show_glyphs_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_SHOW_GLYPHS;
|
||||
command->scaled_font = cairo_scaled_font_reference (scaled_font);
|
||||
command->operator = operator;
|
||||
_cairo_pattern_init_copy (&command->pattern.base, pattern);
|
||||
command->source_x = source_x;
|
||||
command->source_y = source_y;
|
||||
command->dest_x = dest_x;
|
||||
command->dest_y = dest_y;
|
||||
command->width = width;
|
||||
command->height = height;
|
||||
|
||||
command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
|
||||
if (command->glyphs == NULL) {
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
||||
|
||||
command->num_glyphs = num_glyphs;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command->glyphs);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
rectangle->width = CAIRO_MAXSHORT;
|
||||
rectangle->height = CAIRO_MAXSHORT;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance)
|
||||
/**
|
||||
* _cairo_surface_is_meta:
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Checks if a surface is a #cairo_meta_surface_t
|
||||
*
|
||||
* Return value: TRUE if the surface is a meta surface
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface)
|
||||
{
|
||||
cairo_meta_surface_t *meta = abstract_surface;
|
||||
cairo_command_fill_path_t *command;
|
||||
cairo_status_t status;
|
||||
|
||||
command = malloc (sizeof (cairo_command_fill_path_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
command->type = CAIRO_COMMAND_FILL_PATH;
|
||||
command->operator = operator;
|
||||
_cairo_pattern_init_copy (&command->pattern.base, pattern);
|
||||
status = _cairo_path_fixed_init_copy (&command->path, path);
|
||||
if (status) {
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
command->fill_rule = fill_rule;
|
||||
command->tolerance = tolerance;
|
||||
|
||||
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
_cairo_pattern_fini (&command->pattern.base);
|
||||
free (command);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return surface->backend == &cairo_meta_surface_backend;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||
_cairo_meta_surface_create_similar,
|
||||
_cairo_meta_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
_cairo_meta_surface_acquire_source_image,
|
||||
_cairo_meta_surface_release_source_image,
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
_cairo_meta_surface_composite,
|
||||
_cairo_meta_surface_fill_rectangles,
|
||||
_cairo_meta_surface_composite_trapezoids,
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_meta_surface_intersect_clip_path,
|
||||
_cairo_meta_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
/* Here are the 5 basic drawing operations, (which are in some
|
||||
* sense the only things that cairo_meta_surface should need to
|
||||
* implement). */
|
||||
|
||||
_cairo_meta_surface_paint,
|
||||
_cairo_meta_surface_mask,
|
||||
_cairo_meta_surface_stroke,
|
||||
_cairo_meta_surface_fill,
|
||||
_cairo_meta_surface_show_glyphs,
|
||||
_cairo_meta_surface_fill_path,
|
||||
|
||||
_cairo_meta_surface_snapshot
|
||||
};
|
||||
|
||||
cairo_int_status_t
|
||||
cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
|
@ -443,7 +597,6 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
cairo_command_t *command, **elements;
|
||||
int i, num_elements;
|
||||
cairo_int_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_clip_t clip;
|
||||
|
||||
meta = (cairo_meta_surface_t *) surface;
|
||||
|
@ -452,61 +605,72 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
_cairo_clip_init (&clip, target);
|
||||
|
||||
num_elements = meta->commands.num_elements;
|
||||
elements = (cairo_command_t **) meta->commands.elements;
|
||||
elements = _cairo_array_index (&meta->commands, 0);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
command = elements[i];
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_COMPOSITE:
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_composite
|
||||
(command->composite.operator,
|
||||
&command->composite.src_pattern.base,
|
||||
command->composite.mask_pattern_pointer,
|
||||
target,
|
||||
command->composite.src_x,
|
||||
command->composite.src_y,
|
||||
command->composite.mask_x,
|
||||
command->composite.mask_y,
|
||||
command->composite.dst_x,
|
||||
command->composite.dst_y,
|
||||
command->composite.width,
|
||||
command->composite.height);
|
||||
status = _cairo_surface_paint (target,
|
||||
command->paint.op,
|
||||
&command->paint.source.base);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL_RECTANGLES:
|
||||
case CAIRO_COMMAND_MASK:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_fill_rectangles
|
||||
(target,
|
||||
command->fill_rectangles.operator,
|
||||
&command->fill_rectangles.color,
|
||||
command->fill_rectangles.rects,
|
||||
command->fill_rectangles.num_rects);
|
||||
status = _cairo_surface_mask (target,
|
||||
command->mask.op,
|
||||
&command->mask.source.base,
|
||||
&command->mask.mask.base);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
|
||||
case CAIRO_COMMAND_STROKE:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_composite_trapezoids
|
||||
(command->composite_trapezoids.operator,
|
||||
&command->composite_trapezoids.pattern.base,
|
||||
target,
|
||||
command->composite_trapezoids.antialias,
|
||||
command->composite_trapezoids.x_src,
|
||||
command->composite_trapezoids.y_src,
|
||||
command->composite_trapezoids.x_dst,
|
||||
command->composite_trapezoids.y_dst,
|
||||
command->composite_trapezoids.width,
|
||||
command->composite_trapezoids.height,
|
||||
command->composite_trapezoids.traps,
|
||||
command->composite_trapezoids.num_traps);
|
||||
status = _cairo_surface_stroke (target,
|
||||
command->stroke.op,
|
||||
&command->stroke.source.base,
|
||||
&command->stroke.path,
|
||||
&command->stroke.style,
|
||||
&command->stroke.ctm,
|
||||
&command->stroke.ctm_inverse,
|
||||
command->stroke.tolerance,
|
||||
command->stroke.antialias);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_fill (target,
|
||||
command->fill.op,
|
||||
&command->fill.source.base,
|
||||
&command->fill.path,
|
||||
command->fill.fill_rule,
|
||||
command->fill.tolerance,
|
||||
command->fill.antialias);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_show_glyphs (target,
|
||||
command->show_glyphs.op,
|
||||
&command->show_glyphs.source.base,
|
||||
command->show_glyphs.glyphs,
|
||||
command->show_glyphs.num_glyphs,
|
||||
command->show_glyphs.scaled_font);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
|
@ -523,78 +687,6 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
target);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_show_glyphs
|
||||
(command->show_glyphs.scaled_font,
|
||||
command->show_glyphs.operator,
|
||||
&command->show_glyphs.pattern.base,
|
||||
target,
|
||||
command->show_glyphs.source_x,
|
||||
command->show_glyphs.source_y,
|
||||
command->show_glyphs.dest_x,
|
||||
command->show_glyphs.dest_y,
|
||||
command->show_glyphs.width,
|
||||
command->show_glyphs.height,
|
||||
command->show_glyphs.glyphs,
|
||||
command->show_glyphs.num_glyphs);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
break;
|
||||
|
||||
status = (*command->show_glyphs.scaled_font->backend->
|
||||
show_glyphs) (command->show_glyphs.scaled_font,
|
||||
command->show_glyphs.operator,
|
||||
&command->show_glyphs.pattern.base,
|
||||
target,
|
||||
command->show_glyphs.source_x,
|
||||
command->show_glyphs.source_y,
|
||||
command->show_glyphs.dest_x,
|
||||
command->show_glyphs.dest_y,
|
||||
command->show_glyphs.width,
|
||||
command->show_glyphs.height,
|
||||
command->show_glyphs.glyphs,
|
||||
command->show_glyphs.num_glyphs);
|
||||
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL_PATH:
|
||||
status = _cairo_surface_set_clip (target, &clip);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = _cairo_surface_fill_path (command->fill_path.operator,
|
||||
&command->fill_path.pattern.base,
|
||||
target,
|
||||
&command->fill_path.path,
|
||||
command->fill_path.fill_rule,
|
||||
command->fill_path.tolerance);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
break;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
status = _cairo_path_fixed_fill_to_traps (&command->fill_path.path,
|
||||
command->fill_path.fill_rule,
|
||||
command->fill_path.tolerance,
|
||||
&traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
break;
|
||||
}
|
||||
|
||||
status = _cairo_surface_clip_and_composite_trapezoids (&command->fill_path.pattern.base,
|
||||
command->fill_path.operator,
|
||||
target,
|
||||
&traps,
|
||||
&clip,
|
||||
command->fill_path.antialias);
|
||||
|
||||
_cairo_traps_fini (&traps);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
|
|
@ -119,8 +119,8 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
|||
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
|
||||
*/
|
||||
|
||||
static int
|
||||
dtostr (char *buffer, size_t size, double d)
|
||||
int
|
||||
_cairo_dtostr (char *buffer, size_t size, double d)
|
||||
{
|
||||
struct lconv *locale_data;
|
||||
const char *decimal_point;
|
||||
|
@ -233,7 +233,7 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
|||
snprintf (buffer, sizeof buffer, "%s", va_arg (ap, const char *));
|
||||
break;
|
||||
case 'f':
|
||||
dtostr (buffer, sizeof buffer, va_arg (ap, double));
|
||||
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double));
|
||||
break;
|
||||
case 'c':
|
||||
buffer[0] = va_arg (ap, int);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PAGINATED_SURFACE_H
|
||||
#define CAIRO_PAGINATED_SURFACE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
#endif /* CAIRO_PAGINATED_SURFACE_H */
|
|
@ -0,0 +1,400 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
/* The paginated surface layer exists to provide as much code sharing
|
||||
* as possible for the various paginated surface backends in cairo
|
||||
* (PostScript, PDF, etc.).
|
||||
*
|
||||
* The concept is that a surface which uses a paginated surface merely
|
||||
* needs to implement backend operations which it can accurately
|
||||
* provide, (and return CAIRO_INT_STATUS_UNSUPPORTED or leave backend
|
||||
* function pointers NULL otherwise). The paginated surface is the
|
||||
* responsible for collecting operations that aren't supported,
|
||||
* replaying them against the image surface, and then supplying the
|
||||
* resulting images to the target surface.
|
||||
*
|
||||
* When created, a paginated surface accepts the target surface to
|
||||
* which the final drawing will eventually be performed. The paginated
|
||||
* surface then uses cairo_meta_surface_t to record all drawing
|
||||
* operations up until each show_page operation.
|
||||
*
|
||||
* At the time of show_page, the paginated surface replays the meta
|
||||
* surface against the target surface and maintains regions of the
|
||||
* result that will come from the nativ surface and regions that will
|
||||
* need to come from image fallbacks. It then replays the necessary
|
||||
* portions against image surface and provides those results to the
|
||||
* target surface through existing interfaces.
|
||||
*
|
||||
* This way the target surface is never even aware of any distinction
|
||||
* between native drawing operations vs. results that are supplied by
|
||||
* image fallbacks. Instead the surface need only implement as much of
|
||||
* the surface backend interface as it can do correctly, and let the
|
||||
* paginated surface take care of all the messy details.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
typedef struct _cairo_paginated_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* XXX: These shouldn't actually exist. We inherit this ugliness
|
||||
* from _cairo_meta_surface_create. The width/height parameters
|
||||
* from that function also should not exist. The fix that will
|
||||
* allow us to remove all of these is to fix acquire_source_image
|
||||
* to pass an interest rectangle. */
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* The target surface to hold the final result. */
|
||||
cairo_surface_t *target;
|
||||
|
||||
/* A cairo_meta_surface to record all operations. To be replayed
|
||||
* against target, and also against image surface as necessary for
|
||||
* fallbacks. */
|
||||
cairo_surface_t *meta;
|
||||
|
||||
} cairo_paginated_surface_t;
|
||||
|
||||
const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *surface;
|
||||
|
||||
surface = malloc (sizeof (cairo_paginated_surface_t));
|
||||
if (surface == NULL)
|
||||
goto FAIL;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend);
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->target = target;
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (width, height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
goto FAIL_CLEANUP_SURFACE;
|
||||
|
||||
return &surface->base;
|
||||
|
||||
FAIL_CLEANUP_SURFACE:
|
||||
free (surface);
|
||||
FAIL:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_paginated_surface_finish (void *abstract_surface)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
cairo_surface_destroy (surface->target);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
cairo_rectangle_t extents;
|
||||
|
||||
_cairo_surface_get_extents (surface->target, &extents);
|
||||
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
extents.width, extents.height);
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
||||
*image_out = (cairo_image_surface_t*) image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_paginated_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static void
|
||||
_paint_page (cairo_paginated_surface_t *surface)
|
||||
{
|
||||
cairo_surface_t *image;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
surface->width, surface->height);
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (image);
|
||||
|
||||
_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_surface_destroy (image);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_copy_page (void *abstract_surface)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_int_status_t status;
|
||||
|
||||
_paint_page (surface);
|
||||
|
||||
status = _cairo_surface_copy_page (surface->target);
|
||||
|
||||
/* If the surface does not support copy_page then we use show_page
|
||||
* instead, and we leave the meta-surface untouched so that its
|
||||
* contents will remain for the next page. */
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
status = _cairo_surface_show_page (surface->target);
|
||||
/* And if the surface doesn't support show_page either, we
|
||||
* also fall through and clear the meta-surface. */
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Otherwise, we clear the meta-surface since the target surface
|
||||
* has already taken care of any copying in its implementation of
|
||||
* copy_page. */
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (surface->width, surface->height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
return cairo_surface_status (surface->meta);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
_paint_page (surface);
|
||||
|
||||
_cairo_surface_show_page (surface->target);
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (surface->width, surface->height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
return cairo_surface_status (surface->meta);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_intersect_clip_path (void *abstract_surface,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_intersect_clip_path (surface->meta,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_paint (surface->meta, op, source);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_mask (surface->meta, op, source, mask);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_stroke (surface->meta, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_fill (surface->meta, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_show_glyphs (surface->meta, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_snapshot (void *abstract_other)
|
||||
{
|
||||
cairo_paginated_surface_t *other = abstract_other;
|
||||
|
||||
/* XXX: Just making a snapshot of other->meta is what we really
|
||||
* want. But this currently triggers a bug somewhere (the "mask"
|
||||
* test from the test suite segfaults).
|
||||
*
|
||||
* For now, we'll create a new image surface and replay onto
|
||||
* that. It would be tempting to replay into other->image and then
|
||||
* return a snapshot of that, but that will cause the self-copy
|
||||
* test to fail, (since our replay will be affected by a clip that
|
||||
* should not have any effect on the use of the resulting snapshot
|
||||
* as a source).
|
||||
*/
|
||||
|
||||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
_cairo_surface_get_extents (other->target, &extents);
|
||||
|
||||
surface = cairo_surface_create_similar (other->target,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
_cairo_meta_surface_replay (other->meta, surface);
|
||||
|
||||
return surface;
|
||||
#endif
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
NULL, /* create_similar */
|
||||
_cairo_paginated_surface_finish,
|
||||
_cairo_paginated_surface_acquire_source_image,
|
||||
_cairo_paginated_surface_release_source_image,
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
_cairo_paginated_surface_copy_page,
|
||||
_cairo_paginated_surface_show_page,
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_paginated_surface_intersect_clip_path,
|
||||
_cairo_paginated_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
_cairo_paginated_surface_paint,
|
||||
_cairo_paginated_surface_mask,
|
||||
_cairo_paginated_surface_stroke,
|
||||
_cairo_paginated_surface_fill,
|
||||
_cairo_paginated_surface_show_glyphs,
|
||||
_cairo_paginated_surface_snapshot
|
||||
};
|
|
@ -36,12 +36,17 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-gstate-private.h"
|
||||
|
||||
typedef struct cairo_stroker {
|
||||
cairo_gstate_t *gstate;
|
||||
cairo_stroke_style_t *style;
|
||||
|
||||
cairo_matrix_t *ctm;
|
||||
cairo_matrix_t *ctm_inverse;
|
||||
double tolerance;
|
||||
|
||||
cairo_traps_t *traps;
|
||||
|
||||
cairo_pen_t pen;
|
||||
|
||||
cairo_bool_t has_current_point;
|
||||
cairo_point_t current_point;
|
||||
cairo_point_t first_point;
|
||||
|
@ -60,7 +65,12 @@ typedef struct cairo_stroker {
|
|||
|
||||
/* private functions */
|
||||
static void
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps);
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps);
|
||||
|
||||
static void
|
||||
_cairo_stroker_fini (cairo_stroker_t *stroker);
|
||||
|
@ -101,49 +111,59 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
static void
|
||||
_cairo_stroker_start_dash (cairo_stroker_t *stroker)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
double offset;
|
||||
int on = 1;
|
||||
int i = 0;
|
||||
|
||||
offset = gstate->dash_offset;
|
||||
while (offset >= gstate->dash[i]) {
|
||||
offset -= gstate->dash[i];
|
||||
offset = stroker->style->dash_offset;
|
||||
while (offset >= stroker->style->dash[i]) {
|
||||
offset -= stroker->style->dash[i];
|
||||
on = 1-on;
|
||||
if (++i == gstate->num_dashes)
|
||||
if (++i == stroker->style->num_dashes)
|
||||
i = 0;
|
||||
}
|
||||
stroker->dashed = TRUE;
|
||||
stroker->dash_index = i;
|
||||
stroker->dash_on = on;
|
||||
stroker->dash_remain = gstate->dash[i] - offset;
|
||||
stroker->dash_remain = stroker->style->dash[i] - offset;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_stroker_step_dash (cairo_stroker_t *stroker, double step)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
stroker->dash_remain -= step;
|
||||
if (stroker->dash_remain <= 0) {
|
||||
stroker->dash_index++;
|
||||
if (stroker->dash_index == gstate->num_dashes)
|
||||
if (stroker->dash_index == stroker->style->num_dashes)
|
||||
stroker->dash_index = 0;
|
||||
stroker->dash_on = 1-stroker->dash_on;
|
||||
stroker->dash_remain = gstate->dash[stroker->dash_index];
|
||||
stroker->dash_remain = stroker->style->dash[stroker->dash_index];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps)
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
stroker->gstate = gstate;
|
||||
stroker->style = stroke_style;
|
||||
stroker->ctm = ctm;
|
||||
stroker->ctm_inverse = ctm_inverse;
|
||||
stroker->tolerance = tolerance;
|
||||
stroker->traps = traps;
|
||||
|
||||
_cairo_pen_init (&stroker->pen,
|
||||
stroke_style->line_width / 2.0,
|
||||
tolerance, ctm);
|
||||
|
||||
stroker->has_current_point = FALSE;
|
||||
stroker->has_current_face = FALSE;
|
||||
stroker->has_first_face = FALSE;
|
||||
|
||||
if (gstate->dash)
|
||||
if (stroker->style->dash)
|
||||
_cairo_stroker_start_dash (stroker);
|
||||
else
|
||||
stroker->dashed = FALSE;
|
||||
|
@ -152,7 +172,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_tra
|
|||
static void
|
||||
_cairo_stroker_fini (cairo_stroker_t *stroker)
|
||||
{
|
||||
/* nothing to do here */
|
||||
_cairo_pen_fini (&stroker->pen);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -177,8 +197,7 @@ static cairo_status_t
|
|||
_cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_stroke_face_t *out)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
cairo_point_t *inpt, *outpt;
|
||||
|
||||
if (in->cw.x == out->cw.x
|
||||
|
@ -196,12 +215,12 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
outpt = &out->cw;
|
||||
}
|
||||
|
||||
switch (gstate->line_join) {
|
||||
switch (stroker->style->line_join) {
|
||||
case CAIRO_LINE_JOIN_ROUND: {
|
||||
int i;
|
||||
int start, step, stop;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
cairo_pen_t *pen = &stroker->pen;
|
||||
|
||||
tri[0] = in->point;
|
||||
if (clockwise) {
|
||||
|
@ -237,7 +256,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
/* dot product of incoming slope vector with outgoing slope vector */
|
||||
double in_dot_out = ((-in->usr_vector.x * out->usr_vector.x)+
|
||||
(-in->usr_vector.y * out->usr_vector.y));
|
||||
double ml = gstate->miter_limit;
|
||||
double ml = stroker->style->miter_limit;
|
||||
|
||||
/*
|
||||
* Check the miter limit -- lines meeting at an acute angle
|
||||
|
@ -285,14 +304,14 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
y1 = _cairo_fixed_to_double (inpt->y);
|
||||
dx1 = in->usr_vector.x;
|
||||
dy1 = in->usr_vector.y;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx1, &dy1);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1);
|
||||
|
||||
/* outer point of outgoing line face */
|
||||
x2 = _cairo_fixed_to_double (outpt->x);
|
||||
y2 = _cairo_fixed_to_double (outpt->y);
|
||||
dx2 = out->usr_vector.x;
|
||||
dy2 = out->usr_vector.y;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2);
|
||||
|
||||
/*
|
||||
* Compute the location of the outer corner of the miter.
|
||||
|
@ -344,18 +363,17 @@ static cairo_status_t
|
|||
_cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
|
||||
if (gstate->line_cap == CAIRO_LINE_CAP_BUTT)
|
||||
if (stroker->style->line_cap == CAIRO_LINE_CAP_BUTT)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
switch (gstate->line_cap) {
|
||||
switch (stroker->style->line_cap) {
|
||||
case CAIRO_LINE_CAP_ROUND: {
|
||||
int i;
|
||||
int start, stop;
|
||||
cairo_slope_t slope;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
cairo_pen_t *pen = &stroker->pen;
|
||||
|
||||
slope = f->dev_vector;
|
||||
_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
|
||||
|
@ -383,9 +401,9 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
|
||||
dx = f->usr_vector.x;
|
||||
dy = f->usr_vector.y;
|
||||
dx *= gstate->line_width / 2.0;
|
||||
dy *= gstate->line_width / 2.0;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
dx *= stroker->style->line_width / 2.0;
|
||||
dy *= stroker->style->line_width / 2.0;
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx, &dy);
|
||||
fvector.dx = _cairo_fixed_from_double (dx);
|
||||
fvector.dy = _cairo_fixed_from_double (dy);
|
||||
occw.x = f->ccw.x + fvector.dx;
|
||||
|
@ -460,7 +478,7 @@ _cairo_stroker_add_caps (cairo_stroker_t *stroker)
|
|||
}
|
||||
|
||||
static void
|
||||
_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_stroker_t *stroker, cairo_stroke_face_t *face)
|
||||
{
|
||||
double mag, det;
|
||||
double line_dx, line_dy;
|
||||
|
@ -472,7 +490,7 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat
|
|||
line_dy = _cairo_fixed_to_double (slope->dy);
|
||||
|
||||
/* faces are normal in user space, not device space */
|
||||
cairo_matrix_transform_distance (&gstate->ctm_inverse, &line_dx, &line_dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm_inverse, &line_dx, &line_dy);
|
||||
|
||||
mag = sqrt (line_dx * line_dx + line_dy * line_dy);
|
||||
if (mag == 0) {
|
||||
|
@ -494,20 +512,20 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat
|
|||
* whether the ctm reflects or not, and that can be determined
|
||||
* by looking at the determinant of the matrix.
|
||||
*/
|
||||
_cairo_matrix_compute_determinant (&gstate->ctm, &det);
|
||||
_cairo_matrix_compute_determinant (stroker->ctm, &det);
|
||||
if (det >= 0)
|
||||
{
|
||||
face_dx = - line_dy * (gstate->line_width / 2.0);
|
||||
face_dy = line_dx * (gstate->line_width / 2.0);
|
||||
face_dx = - line_dy * (stroker->style->line_width / 2.0);
|
||||
face_dy = line_dx * (stroker->style->line_width / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
face_dx = line_dy * (gstate->line_width / 2.0);
|
||||
face_dy = - line_dx * (gstate->line_width / 2.0);
|
||||
face_dx = line_dy * (stroker->style->line_width / 2.0);
|
||||
face_dy = - line_dx * (stroker->style->line_width / 2.0);
|
||||
}
|
||||
|
||||
/* back to device space */
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &face_dx, &face_dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy);
|
||||
|
||||
offset_ccw.x = _cairo_fixed_from_double (face_dx);
|
||||
offset_ccw.y = _cairo_fixed_from_double (face_dy);
|
||||
|
@ -533,7 +551,6 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
|
|||
cairo_stroke_face_t *start, cairo_stroke_face_t *end)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_polygon_t polygon;
|
||||
cairo_slope_t slope;
|
||||
|
||||
|
@ -545,12 +562,12 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
|
|||
}
|
||||
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
_compute_face (p1, &slope, gstate, start);
|
||||
_compute_face (p1, &slope, stroker, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
_compute_face again but rather translating the relevant
|
||||
fields from start. */
|
||||
_compute_face (p2, &slope, gstate, end);
|
||||
_compute_face (p2, &slope, stroker, end);
|
||||
|
||||
/* XXX: I should really check the return value of the
|
||||
move_to/line_to functions here to catch out of memory
|
||||
|
@ -648,7 +665,6 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
double mag, remain, tmp;
|
||||
double dx, dy;
|
||||
double dx2, dy2;
|
||||
|
@ -664,7 +680,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
dx = _cairo_fixed_to_double (p2->x - p1->x);
|
||||
dy = _cairo_fixed_to_double (p2->y - p1->y);
|
||||
|
||||
cairo_matrix_transform_distance (&gstate->ctm_inverse, &dx, &dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm_inverse, &dx, &dy);
|
||||
|
||||
mag = sqrt (dx *dx + dy * dy);
|
||||
remain = mag;
|
||||
|
@ -676,7 +692,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
remain -= tmp;
|
||||
dx2 = dx * (mag - remain)/mag;
|
||||
dy2 = dy * (mag - remain)/mag;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2);
|
||||
fd2.x = _cairo_fixed_from_double (dx2);
|
||||
fd2.y = _cairo_fixed_from_double (dy2);
|
||||
fd2.x += p1->x;
|
||||
|
@ -764,7 +780,6 @@ _cairo_stroker_curve_to (void *closure,
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_spline_t spline;
|
||||
cairo_pen_t pen;
|
||||
cairo_stroke_face_t start, end;
|
||||
|
@ -775,12 +790,12 @@ _cairo_stroker_curve_to (void *closure,
|
|||
if (status == CAIRO_INT_STATUS_DEGENERATE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_pen_init_copy (&pen, &gstate->pen_regular);
|
||||
status = _cairo_pen_init_copy (&pen, &stroker->pen);
|
||||
if (status)
|
||||
goto CLEANUP_SPLINE;
|
||||
|
||||
_compute_face (a, &spline.initial_slope, gstate, &start);
|
||||
_compute_face (d, &spline.final_slope, gstate, &end);
|
||||
_compute_face (a, &spline.initial_slope, stroker, &start);
|
||||
_compute_face (d, &spline.final_slope, stroker, &end);
|
||||
|
||||
if (stroker->has_current_face) {
|
||||
status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
|
||||
|
@ -812,7 +827,7 @@ _cairo_stroker_curve_to (void *closure,
|
|||
if (status)
|
||||
goto CLEANUP_PEN;
|
||||
|
||||
status = _cairo_pen_stroke_spline (&pen, &spline, gstate->tolerance, stroker->traps);
|
||||
status = _cairo_pen_stroke_spline (&pen, &spline, stroker->tolerance, stroker->traps);
|
||||
if (status)
|
||||
goto CLEANUP_PEN;
|
||||
|
||||
|
@ -852,7 +867,6 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_spline_t spline;
|
||||
cairo_point_t *a = &stroker->current_point;
|
||||
cairo_line_join_t line_join_save;
|
||||
|
@ -864,15 +878,15 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
|
||||
/* If the line width is so small that the pen is reduced to a
|
||||
single point, then we have nothing to do. */
|
||||
if (gstate->pen_regular.num_vertices <= 1)
|
||||
if (stroker->pen.num_vertices <= 1)
|
||||
goto CLEANUP_SPLINE;
|
||||
|
||||
/* Temporarily modify the gstate to use round joins to guarantee
|
||||
/* Temporarily modify the stroker to use round joins to guarantee
|
||||
* smooth stroked curves. */
|
||||
line_join_save = gstate->line_join;
|
||||
gstate->line_join = CAIRO_LINE_JOIN_ROUND;
|
||||
line_join_save = stroker->style->line_join;
|
||||
stroker->style->line_join = CAIRO_LINE_JOIN_ROUND;
|
||||
|
||||
status = _cairo_spline_decompose (&spline, gstate->tolerance);
|
||||
status = _cairo_spline_decompose (&spline, stroker->tolerance);
|
||||
if (status)
|
||||
goto CLEANUP_GSTATE;
|
||||
|
||||
|
@ -886,7 +900,7 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
}
|
||||
|
||||
CLEANUP_GSTATE:
|
||||
gstate->line_join = line_join_save;
|
||||
stroker->style->line_join = line_join_save;
|
||||
|
||||
CLEANUP_SPLINE:
|
||||
_cairo_spline_fini (&spline);
|
||||
|
@ -923,16 +937,21 @@ _cairo_stroker_close_path (void *closure)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps)
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t stroker;
|
||||
|
||||
_cairo_stroker_init (&stroker, gstate, traps);
|
||||
_cairo_stroker_init (&stroker, stroke_style,
|
||||
ctm, ctm_inverse, tolerance,
|
||||
traps);
|
||||
|
||||
if (gstate->dash)
|
||||
if (stroker.style->dash)
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_stroker_move_to,
|
||||
|
|
|
@ -548,3 +548,40 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley)
|
||||
{
|
||||
cairo_path_arg_buf_t *arg_buf = path->arg_buf_head;
|
||||
int i;
|
||||
cairo_int64_t i64temp;
|
||||
cairo_fixed_t fixedtemp;
|
||||
|
||||
while (arg_buf) {
|
||||
for (i = 0; i < arg_buf->num_points; i++) {
|
||||
/* CAIRO_FIXED_ONE? */
|
||||
if (scalex == 0x00010000) {
|
||||
arg_buf->points[i].x += offx;
|
||||
} else {
|
||||
fixedtemp = arg_buf->points[i].x + offx;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scalex);
|
||||
arg_buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
|
||||
if (scaley == 0x00010000) {
|
||||
arg_buf->points[i].y += offy;
|
||||
} else {
|
||||
fixedtemp = arg_buf->points[i].y + offy;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scaley);
|
||||
arg_buf->points[i].y = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
}
|
||||
|
||||
arg_buf = arg_buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,35 +22,20 @@
|
|||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: David Reveman <davidr@novell.com>
|
||||
* Authors: David Reveman <davidr@novell.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _cairo_shader_color_stop {
|
||||
cairo_fixed_t offset;
|
||||
cairo_fixed_48_16_t scale;
|
||||
int id;
|
||||
unsigned char color_char[4];
|
||||
} cairo_shader_color_stop_t;
|
||||
|
||||
typedef struct _cairo_shader_op {
|
||||
cairo_shader_color_stop_t *stops;
|
||||
int n_stops;
|
||||
cairo_extend_t extend;
|
||||
} cairo_shader_op_t;
|
||||
|
||||
#define MULTIPLY_COLORCOMP(c1, c2) \
|
||||
((unsigned char) \
|
||||
((((unsigned char) (c1)) * (int) ((unsigned char) (c2))) / 0xff))
|
||||
|
||||
const cairo_solid_pattern_t cairo_pattern_nil = {
|
||||
{ CAIRO_PATTERN_SOLID, /* type */
|
||||
(unsigned int)-1, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_DEFAULT }, /* extend */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
|
||||
|
@ -59,7 +44,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
|
|||
CAIRO_STATUS_NULL_POINTER,/* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_DEFAULT }, /* extend */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
|
||||
|
@ -68,7 +53,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_file_not_found = {
|
|||
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_DEFAULT }, /* extend */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {
|
||||
|
@ -77,7 +62,7 @@ static const cairo_solid_pattern_t cairo_pattern_nil_read_error = {
|
|||
CAIRO_STATUS_READ_ERROR, /* status */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_DEFAULT }, /* extend */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
static const cairo_pattern_t *
|
||||
|
@ -131,7 +116,12 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
|
|||
pattern->type = type;
|
||||
pattern->ref_count = 1;
|
||||
pattern->status = CAIRO_STATUS_SUCCESS;
|
||||
pattern->extend = CAIRO_EXTEND_DEFAULT;
|
||||
|
||||
if (type == CAIRO_PATTERN_SURFACE)
|
||||
pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;
|
||||
else
|
||||
pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
|
||||
|
||||
pattern->filter = CAIRO_FILTER_DEFAULT;
|
||||
|
||||
cairo_matrix_init_identity (&pattern->matrix);
|
||||
|
@ -158,14 +148,15 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
|
|||
|
||||
if (other->n_stops)
|
||||
{
|
||||
pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
|
||||
pattern->stops = malloc (other->n_stops *
|
||||
sizeof (pixman_gradient_stop_t));
|
||||
if (pattern->stops == NULL) {
|
||||
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (pattern->stops, other->stops,
|
||||
other->n_stops * sizeof (cairo_color_stop_t));
|
||||
other->n_stops * sizeof (pixman_gradient_stop_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,11 +257,11 @@ _cairo_pattern_init_linear (cairo_linear_pattern_t *pattern,
|
|||
double x0, double y0, double x1, double y1)
|
||||
{
|
||||
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_LINEAR);
|
||||
|
||||
pattern->point0.x = x0;
|
||||
pattern->point0.y = y0;
|
||||
pattern->point1.x = x1;
|
||||
pattern->point1.y = y1;
|
||||
|
||||
pattern->gradient.p1.x = _cairo_fixed_from_double (x0);
|
||||
pattern->gradient.p1.y = _cairo_fixed_from_double (y0);
|
||||
pattern->gradient.p2.x = _cairo_fixed_from_double (x1);
|
||||
pattern->gradient.p2.y = _cairo_fixed_from_double (y1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -280,12 +271,12 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
|
|||
{
|
||||
_cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_RADIAL);
|
||||
|
||||
pattern->center0.x = cx0;
|
||||
pattern->center0.y = cy0;
|
||||
pattern->radius0 = fabs (radius0);
|
||||
pattern->center1.x = cx1;
|
||||
pattern->center1.y = cy1;
|
||||
pattern->radius1 = fabs (radius1);
|
||||
pattern->gradient.inner.x = _cairo_fixed_from_double (cx0);
|
||||
pattern->gradient.inner.y = _cairo_fixed_from_double (cy0);
|
||||
pattern->gradient.inner.radius = _cairo_fixed_from_double (fabs (radius0));
|
||||
pattern->gradient.outer.x = _cairo_fixed_from_double (cx1);
|
||||
pattern->gradient.outer.y = _cairo_fixed_from_double (cy1);
|
||||
pattern->gradient.outer.radius = _cairo_fixed_from_double (fabs (radius1));
|
||||
}
|
||||
|
||||
cairo_pattern_t *
|
||||
|
@ -579,25 +570,45 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
|
|||
static void
|
||||
_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
|
||||
double offset,
|
||||
cairo_color_t *color)
|
||||
double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha)
|
||||
{
|
||||
cairo_color_stop_t *stop;
|
||||
cairo_color_stop_t *new_stops;
|
||||
pixman_gradient_stop_t *new_stops;
|
||||
cairo_fixed_t x;
|
||||
int i;
|
||||
|
||||
pattern->n_stops++;
|
||||
new_stops = realloc (pattern->stops,
|
||||
pattern->n_stops * sizeof (cairo_color_stop_t));
|
||||
if (new_stops == NULL) {
|
||||
new_stops = realloc (pattern->stops, (pattern->n_stops + 1) *
|
||||
sizeof (pixman_gradient_stop_t));
|
||||
if (new_stops == NULL)
|
||||
{
|
||||
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pattern->stops = new_stops;
|
||||
|
||||
stop = &pattern->stops[pattern->n_stops - 1];
|
||||
x = _cairo_fixed_from_double (offset);
|
||||
for (i = 0; i < pattern->n_stops; i++)
|
||||
{
|
||||
if (x < new_stops[i].x)
|
||||
{
|
||||
memmove (&new_stops[i + 1], &new_stops[i],
|
||||
sizeof (pixman_gradient_stop_t) * (pattern->n_stops - i));
|
||||
|
||||
stop->offset = _cairo_fixed_from_double (offset);
|
||||
stop->color = *color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_stops[i].x = x;
|
||||
|
||||
new_stops[i].color.red = red * 65535.0;
|
||||
new_stops[i].color.green = green * 65535.0;
|
||||
new_stops[i].color.blue = blue * 65535.0;
|
||||
new_stops[i].color.alpha = alpha * 65535.0;
|
||||
|
||||
pattern->n_stops++;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -627,8 +638,6 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
|
|||
double green,
|
||||
double blue)
|
||||
{
|
||||
cairo_color_t color;
|
||||
|
||||
if (pattern->status)
|
||||
return;
|
||||
|
||||
|
@ -644,10 +653,8 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
|
|||
_cairo_restrict_value (&green, 0.0, 1.0);
|
||||
_cairo_restrict_value (&blue, 0.0, 1.0);
|
||||
|
||||
_cairo_color_init_rgb (&color, red, green, blue);
|
||||
_cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
|
||||
offset,
|
||||
&color);
|
||||
offset, red, green, blue, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -679,8 +686,6 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
|
|||
double blue,
|
||||
double alpha)
|
||||
{
|
||||
cairo_color_t color;
|
||||
|
||||
if (pattern->status)
|
||||
return;
|
||||
|
||||
|
@ -697,10 +702,8 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
|
|||
_cairo_restrict_value (&blue, 0.0, 1.0);
|
||||
_cairo_restrict_value (&alpha, 0.0, 1.0);
|
||||
|
||||
_cairo_color_init_rgba (&color, red, green, blue, alpha);
|
||||
_cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
|
||||
offset,
|
||||
&color);
|
||||
offset, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -773,6 +776,16 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
|
|||
return pattern->filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_set_extend:
|
||||
* @pattern: a #cairo_pattern_t
|
||||
* @extend: a #cairo_extend_t describing how the area outside of the
|
||||
* pattern will be drawn
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
void
|
||||
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
|
||||
{
|
||||
|
@ -782,6 +795,16 @@ cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
|
|||
pattern->extend = extend;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_extend:
|
||||
* @pattern: a #cairo_pattern_t
|
||||
*
|
||||
* Gets the current extend mode for a pattern. See #cairo_extend_t
|
||||
* for details on the semantics of each extend strategy.
|
||||
*
|
||||
* Return value: the current extend strategy used for drawing the
|
||||
* pattern.
|
||||
**/
|
||||
cairo_extend_t
|
||||
cairo_pattern_get_extend (cairo_pattern_t *pattern)
|
||||
{
|
||||
|
@ -797,230 +820,6 @@ _cairo_pattern_transform (cairo_pattern_t *pattern,
|
|||
cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix);
|
||||
}
|
||||
|
||||
#define INTERPOLATE_COLOR_LINEAR(c1, c2, factor) \
|
||||
(((c2 * factor) + (c1 * (65536 - factor))) / 65536)
|
||||
|
||||
static void
|
||||
_cairo_pattern_shader_linear (unsigned char *color0,
|
||||
unsigned char *color1,
|
||||
cairo_fixed_t factor,
|
||||
uint32_t *pixel)
|
||||
{
|
||||
*pixel = ((INTERPOLATE_COLOR_LINEAR (color0[3], color1[3], factor) << 24) |
|
||||
(INTERPOLATE_COLOR_LINEAR (color0[0], color1[0], factor) << 16) |
|
||||
(INTERPOLATE_COLOR_LINEAR (color0[1], color1[1], factor) << 8) |
|
||||
(INTERPOLATE_COLOR_LINEAR (color0[2], color1[2], factor) << 0));
|
||||
}
|
||||
|
||||
#undef INTERPOLATE_COLOR_LINEAR
|
||||
|
||||
static int
|
||||
_cairo_shader_color_stop_compare (const void *elem1, const void *elem2)
|
||||
{
|
||||
cairo_shader_color_stop_t *s1 = (cairo_shader_color_stop_t *) elem1;
|
||||
cairo_shader_color_stop_t *s2 = (cairo_shader_color_stop_t *) elem2;
|
||||
|
||||
return
|
||||
(s1->offset == s2->offset) ?
|
||||
/* equal offsets, sort on id */
|
||||
((s1->id < s2->id) ? -1 : 1) :
|
||||
/* sort on offset */
|
||||
((s1->offset < s2->offset) ? -1 : 1);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pattern_shader_init (cairo_gradient_pattern_t *pattern,
|
||||
cairo_shader_op_t *op)
|
||||
{
|
||||
int i;
|
||||
|
||||
op->stops = malloc (pattern->n_stops * sizeof (cairo_shader_color_stop_t));
|
||||
if (!op->stops)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < pattern->n_stops; i++)
|
||||
{
|
||||
op->stops[i].color_char[0] = pattern->stops[i].color.red * 0xff;
|
||||
op->stops[i].color_char[1] = pattern->stops[i].color.green * 0xff;
|
||||
op->stops[i].color_char[2] = pattern->stops[i].color.blue * 0xff;
|
||||
op->stops[i].color_char[3] = pattern->stops[i].color.alpha * 0xff;
|
||||
op->stops[i].offset = pattern->stops[i].offset;
|
||||
op->stops[i].id = i;
|
||||
}
|
||||
|
||||
/* sort stops in ascending order */
|
||||
qsort (op->stops, pattern->n_stops, sizeof (cairo_shader_color_stop_t),
|
||||
_cairo_shader_color_stop_compare);
|
||||
|
||||
/* this scale value is used only when computing gradient values
|
||||
* before the defined range, in which case stop 0 is used for both
|
||||
* ends of the interpolation, making the value of 'scale' not
|
||||
* actually matter, except that valgrind notices we're using
|
||||
* an undefined value.
|
||||
*/
|
||||
op->stops[0].scale = 0;
|
||||
for (i = 0; i < pattern->n_stops - 1; i++)
|
||||
{
|
||||
op->stops[i + 1].scale = op->stops[i + 1].offset - op->stops[i].offset;
|
||||
if (op->stops[i + 1].scale == 65536)
|
||||
op->stops[i + 1].scale = 0;
|
||||
}
|
||||
|
||||
op->n_stops = pattern->n_stops;
|
||||
op->extend = pattern->base.extend;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pattern_shader_fini (cairo_shader_op_t *op)
|
||||
{
|
||||
if (op->stops)
|
||||
free (op->stops);
|
||||
}
|
||||
|
||||
/* Find two color stops bounding the given offset. If the given offset
|
||||
* is before the first or after the last stop offset, the nearest
|
||||
* offset is returned twice.
|
||||
*/
|
||||
static void
|
||||
_cairo_shader_op_find_color_stops (cairo_shader_op_t *op,
|
||||
cairo_fixed_t offset,
|
||||
cairo_shader_color_stop_t *stops[2])
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Before first stop. */
|
||||
if (offset <= op->stops[0].offset) {
|
||||
stops[0] = &op->stops[0];
|
||||
stops[1] = &op->stops[0];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Between two stops. */
|
||||
for (i = 0; i < op->n_stops - 1; i++) {
|
||||
if (offset <= op->stops[i + 1].offset) {
|
||||
stops[0] = &op->stops[i];
|
||||
stops[1] = &op->stops[i + 1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* After last stop. */
|
||||
stops[0] = &op->stops[op->n_stops - 1];
|
||||
stops[1] = &op->stops[op->n_stops - 1];
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pattern_calc_color_at_pixel (cairo_shader_op_t *op,
|
||||
cairo_fixed_t factor,
|
||||
uint32_t *pixel)
|
||||
{
|
||||
cairo_shader_color_stop_t *stops[2];
|
||||
|
||||
switch (op->extend) {
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
factor -= factor & 0xffff0000;
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
if (factor < 0 || factor > 65536) {
|
||||
if ((factor >> 16) % 2)
|
||||
factor = 65536 - (factor - (factor & 0xffff0000));
|
||||
else
|
||||
factor -= factor & 0xffff0000;
|
||||
}
|
||||
break;
|
||||
case CAIRO_EXTEND_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
_cairo_shader_op_find_color_stops (op, factor, stops);
|
||||
|
||||
/* take offset as new 0 of coordinate system */
|
||||
factor -= stops[0]->offset;
|
||||
|
||||
/* difference between two offsets == 0, abrubt change */
|
||||
if (stops[1]->scale)
|
||||
factor = ((cairo_fixed_48_16_t) factor << 16) /
|
||||
stops[1]->scale;
|
||||
|
||||
_cairo_pattern_shader_linear (stops[0]->color_char,
|
||||
stops[1]->color_char,
|
||||
factor, pixel);
|
||||
|
||||
/* multiply alpha */
|
||||
if (((unsigned char) (*pixel >> 24)) != 0xff) {
|
||||
*pixel = (*pixel & 0xff000000) |
|
||||
(MULTIPLY_COLORCOMP (*pixel >> 16, *pixel >> 24) << 16) |
|
||||
(MULTIPLY_COLORCOMP (*pixel >> 8, *pixel >> 24) << 8) |
|
||||
(MULTIPLY_COLORCOMP (*pixel >> 0, *pixel >> 24) << 0);
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_image_data_set_linear (cairo_linear_pattern_t *pattern,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
uint32_t *pixels,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int x, y;
|
||||
cairo_point_double_t point0, point1;
|
||||
double a, b, c, d, tx, ty;
|
||||
double scale, start, dx, dy, factor;
|
||||
cairo_shader_op_t op;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_pattern_shader_init (&pattern->base, &op);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* We compute the position in the linear gradient for
|
||||
* a point q as:
|
||||
*
|
||||
* [q . (p1 - p0) - p0 . (p1 - p0)] / (p1 - p0) ^ 2
|
||||
*
|
||||
* The computation is done in pattern space. The
|
||||
* calculation could be heavily optimized by using the
|
||||
* fact that 'factor' increases linearly in both
|
||||
* directions.
|
||||
*/
|
||||
point0.x = pattern->point0.x;
|
||||
point0.y = pattern->point0.y;
|
||||
point1.x = pattern->point1.x;
|
||||
point1.y = pattern->point1.y;
|
||||
|
||||
_cairo_matrix_get_affine (&pattern->base.base.matrix,
|
||||
&a, &b, &c, &d, &tx, &ty);
|
||||
|
||||
dx = point1.x - point0.x;
|
||||
dy = point1.y - point0.y;
|
||||
scale = dx * dx + dy * dy;
|
||||
scale = (scale) ? 1.0 / scale : 1.0;
|
||||
|
||||
start = dx * point0.x + dy * point0.y;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
double qx_device = x + offset_x;
|
||||
double qy_device = y + offset_y;
|
||||
|
||||
/* transform fragment into pattern space */
|
||||
double qx = a * qx_device + c * qy_device + tx;
|
||||
double qy = b * qx_device + d * qy_device + ty;
|
||||
|
||||
factor = ((dx * qx + dy * qy) - start) * scale;
|
||||
|
||||
_cairo_pattern_calc_color_at_pixel (&op, _cairo_fixed_from_double (factor), pixels++);
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_pattern_shader_fini (&op);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_linear_pattern_classify (cairo_linear_pattern_t *pattern,
|
||||
double offset_x,
|
||||
|
@ -1041,10 +840,10 @@ _cairo_linear_pattern_classify (cairo_linear_pattern_t *pattern,
|
|||
* pattern. We actually only need 3/4 corners, so we skip the
|
||||
* fourth.
|
||||
*/
|
||||
point0.x = pattern->point0.x;
|
||||
point0.y = pattern->point0.y;
|
||||
point1.x = pattern->point1.x;
|
||||
point1.y = pattern->point1.y;
|
||||
point0.x = _cairo_fixed_to_double (pattern->gradient.p1.x);
|
||||
point0.y = _cairo_fixed_to_double (pattern->gradient.p1.y);
|
||||
point1.x = _cairo_fixed_to_double (pattern->gradient.p2.x);
|
||||
point1.y = _cairo_fixed_to_double (pattern->gradient.p2.y);
|
||||
|
||||
_cairo_matrix_get_affine (&pattern->base.base.matrix,
|
||||
&a, &b, &c, &d, &tx, &ty);
|
||||
|
@ -1079,131 +878,6 @@ _cairo_linear_pattern_classify (cairo_linear_pattern_t *pattern,
|
|||
*is_horizontal = factors[2] == factors[0];
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_image_data_set_radial (cairo_radial_pattern_t *pattern,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
uint32_t *pixels,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int x, y, aligned_circles;
|
||||
cairo_point_double_t c0, c1;
|
||||
double px, py, ex, ey;
|
||||
double a, b, c, d, tx, ty;
|
||||
double r0, r1, c0_e_x, c0_e_y, c0_e, c1_e_x, c1_e_y, c1_e,
|
||||
c0_c1_x, c0_c1_y, c0_c1, angle_c0, c1_y, y_x, c0_y, c0_x, r1_2,
|
||||
denumerator, fraction, factor;
|
||||
cairo_shader_op_t op;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_pattern_shader_init (&pattern->base, &op);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
c0.x = pattern->center0.x;
|
||||
c0.y = pattern->center0.y;
|
||||
r0 = pattern->radius0;
|
||||
c1.x = pattern->center1.x;
|
||||
c1.y = pattern->center1.y;
|
||||
r1 = pattern->radius1;
|
||||
|
||||
if (c0.x != c1.x || c0.y != c1.y) {
|
||||
aligned_circles = 0;
|
||||
c0_c1_x = c1.x - c0.x;
|
||||
c0_c1_y = c1.y - c0.y;
|
||||
c0_c1 = sqrt (c0_c1_x * c0_c1_x + c0_c1_y * c0_c1_y);
|
||||
r1_2 = r1 * r1;
|
||||
} else {
|
||||
aligned_circles = 1;
|
||||
r1 = 1.0 / (r1 - r0);
|
||||
r1_2 = c0_c1 = 0.0; /* shut up compiler */
|
||||
}
|
||||
|
||||
_cairo_matrix_get_affine (&pattern->base.base.matrix,
|
||||
&a, &b, &c, &d, &tx, &ty);
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
px = x + offset_x;
|
||||
py = y + offset_y;
|
||||
|
||||
/* transform fragment */
|
||||
ex = a * px + c * py + tx;
|
||||
ey = b * px + d * py + ty;
|
||||
|
||||
if (aligned_circles) {
|
||||
ex = ex - c1.x;
|
||||
ey = ey - c1.y;
|
||||
|
||||
factor = (sqrt (ex * ex + ey * ey) - r0) * r1;
|
||||
} else {
|
||||
/*
|
||||
y (ex, ey)
|
||||
c0 -------------------+---------- x
|
||||
\ | __--
|
||||
\ | __--
|
||||
\ | __--
|
||||
\ | __-- r1
|
||||
\ | __--
|
||||
c1 --
|
||||
|
||||
We need to calulate distance c0->x; the distance from
|
||||
the inner circle center c0, through fragment position
|
||||
(ex, ey) to point x where it crosses the outer circle.
|
||||
|
||||
From points c0, c1 and (ex, ey) we get angle C0. With
|
||||
angle C0 we calculate distance c1->y and c0->y and by
|
||||
knowing c1->y and r1, we also know y->x. Adding y->x to
|
||||
c0->y gives us c0->x. The gradient offset can then be
|
||||
calculated as:
|
||||
|
||||
offset = (c0->e - r0) / (c0->x - r0)
|
||||
|
||||
*/
|
||||
|
||||
c0_e_x = ex - c0.x;
|
||||
c0_e_y = ey - c0.y;
|
||||
c0_e = sqrt (c0_e_x * c0_e_x + c0_e_y * c0_e_y);
|
||||
|
||||
c1_e_x = ex - c1.x;
|
||||
c1_e_y = ey - c1.y;
|
||||
c1_e = sqrt (c1_e_x * c1_e_x + c1_e_y * c1_e_y);
|
||||
|
||||
denumerator = -2.0 * c0_e * c0_c1;
|
||||
|
||||
if (denumerator != 0.0) {
|
||||
fraction = (c1_e * c1_e - c0_e * c0_e - c0_c1 * c0_c1) /
|
||||
denumerator;
|
||||
|
||||
if (fraction > 1.0)
|
||||
fraction = 1.0;
|
||||
else if (fraction < -1.0)
|
||||
fraction = -1.0;
|
||||
|
||||
angle_c0 = acos (fraction);
|
||||
|
||||
c0_y = cos (angle_c0) * c0_c1;
|
||||
c1_y = sin (angle_c0) * c0_c1;
|
||||
|
||||
y_x = sqrt (r1_2 - c1_y * c1_y);
|
||||
c0_x = y_x + c0_y;
|
||||
|
||||
factor = (c0_e - r0) / (c0_x - r0);
|
||||
} else {
|
||||
factor = -r0;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_pattern_calc_color_at_pixel (&op, _cairo_fixed_from_double (factor), pixels++);
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_pattern_shader_fini (&op);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
|
@ -1215,9 +889,52 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
|||
cairo_surface_attributes_t *attr)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
cairo_status_t status;
|
||||
uint32_t *data;
|
||||
cairo_bool_t repeat = FALSE;
|
||||
pixman_image_t *pixman_image;
|
||||
pixman_transform_t pixman_transform;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t repeat = FALSE;
|
||||
|
||||
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
|
||||
{
|
||||
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
|
||||
|
||||
pixman_image = pixman_image_create_linear_gradient (&linear->gradient,
|
||||
pattern->stops,
|
||||
pattern->n_stops);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern;
|
||||
|
||||
pixman_image = pixman_image_create_radial_gradient (&radial->gradient,
|
||||
pattern->stops,
|
||||
pattern->n_stops);
|
||||
}
|
||||
|
||||
if (pixman_image == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (_cairo_surface_is_image (dst))
|
||||
{
|
||||
image = (cairo_image_surface_t *)
|
||||
_cairo_image_surface_create_for_pixman_image (pixman_image,
|
||||
CAIRO_FORMAT_ARGB32);
|
||||
if (image->base.status)
|
||||
{
|
||||
pixman_image_destroy (pixman_image);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
attr->x_offset = attr->y_offset = 0;
|
||||
attr->matrix = pattern->base.matrix;
|
||||
attr->extend = pattern->base.extend;
|
||||
attr->filter = CAIRO_FILTER_NEAREST;
|
||||
attr->acquired = FALSE;
|
||||
|
||||
*out = &image->base;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (pattern->base.type == CAIRO_PATTERN_LINEAR) {
|
||||
cairo_bool_t is_horizontal;
|
||||
|
@ -1242,46 +959,47 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
|||
repeat = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
data = malloc (width * height * 4);
|
||||
if (data == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
|
||||
{
|
||||
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
|
||||
|
||||
status = _cairo_image_data_set_linear (linear, x, y, data,
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern;
|
||||
|
||||
status = _cairo_image_data_set_radial (radial, x, y, data,
|
||||
width, height);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
free (data);
|
||||
return status;
|
||||
}
|
||||
|
||||
image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data ((unsigned char *) data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width, height,
|
||||
width * 4);
|
||||
|
||||
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
if (image->base.status) {
|
||||
free (data);
|
||||
pixman_image_destroy (pixman_image);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (image);
|
||||
|
||||
pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR);
|
||||
|
||||
_cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform);
|
||||
pixman_image_set_transform (pixman_image, &pixman_transform);
|
||||
|
||||
switch (pattern->base.extend) {
|
||||
case CAIRO_EXTEND_NONE:
|
||||
pixman_image_set_repeat (pixman_image, PIXMAN_REPEAT_NONE);
|
||||
break;
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
pixman_image_set_repeat (pixman_image, PIXMAN_REPEAT_NORMAL);
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
pixman_image_set_repeat (pixman_image, PIXMAN_REPEAT_REFLECT);
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
pixman_image_set_repeat (pixman_image, PIXMAN_REPEAT_PAD);
|
||||
break;
|
||||
}
|
||||
|
||||
pixman_composite (PIXMAN_OPERATOR_SRC,
|
||||
pixman_image,
|
||||
NULL,
|
||||
image->pixman_image,
|
||||
x, y,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
pixman_image_destroy (pixman_image);
|
||||
|
||||
status = _cairo_surface_clone_similar (dst, &image->base, out);
|
||||
|
||||
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
||||
attr->x_offset = -x;
|
||||
|
@ -1290,7 +1008,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
|||
attr->extend = repeat ? CAIRO_EXTEND_REPEAT : CAIRO_EXTEND_NONE;
|
||||
attr->filter = CAIRO_FILTER_NEAREST;
|
||||
attr->acquired = FALSE;
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1448,15 +1166,27 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
/* fast path for gradients with less than 2 color stops */
|
||||
if (src->n_stops < 2)
|
||||
{
|
||||
const cairo_color_t *color;
|
||||
cairo_solid_pattern_t solid;
|
||||
|
||||
if (src->n_stops)
|
||||
color = &src->stops->color;
|
||||
else
|
||||
color = CAIRO_COLOR_TRANSPARENT;
|
||||
{
|
||||
cairo_color_t color;
|
||||
|
||||
_cairo_pattern_init_solid (&solid, color);
|
||||
_cairo_color_init_rgba (&color,
|
||||
src->stops->color.red / 65536.0,
|
||||
src->stops->color.green / 65536.0,
|
||||
src->stops->color.blue / 65536.0,
|
||||
src->stops->color.alpha / 65536.0);
|
||||
|
||||
_cairo_pattern_init_solid (&solid, &color);
|
||||
}
|
||||
else
|
||||
{
|
||||
const cairo_color_t *color;
|
||||
|
||||
color = _cairo_stock_color (CAIRO_STOCK_TRANSPARENT);
|
||||
_cairo_pattern_init_solid (&solid, color);
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface_for_solid (&solid, dst,
|
||||
x, y,
|
||||
|
@ -1598,3 +1328,85 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_pattern_get_extents:
|
||||
*
|
||||
* Return the "target-space" extents of @pattern in @extents.
|
||||
*
|
||||
* For unbounded patterns, the @extents will be initialized with
|
||||
* "infinite" extents, (minimum and maximum fixed-point values).
|
||||
*
|
||||
* XXX: Currently, bounded gradient patterns will also return
|
||||
* "infinite" extents, though it would be possible to optimize these
|
||||
* with a little more work.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents)
|
||||
{
|
||||
if (pattern->extend == CAIRO_EXTEND_NONE &&
|
||||
pattern->type == CAIRO_PATTERN_SURFACE)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t surface_extents;
|
||||
cairo_surface_pattern_t *surface_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;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &surface_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
imatrix = pattern->matrix;
|
||||
cairo_matrix_invert (&imatrix);
|
||||
|
||||
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_MAXSHORT) x = CAIRO_MAXSHORT;
|
||||
if (y < 0) y = 0;
|
||||
if (y > CAIRO_MAXSHORT) y = CAIRO_MAXSHORT;
|
||||
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;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: We could optimize gradients with pattern->extend of NONE
|
||||
* here in some cases, (eg. radial gradients and 1 axis of
|
||||
* horizontal/vertical linear gradients).
|
||||
*/
|
||||
|
||||
extents->x = 0;
|
||||
extents->y = 0;
|
||||
extents->width = CAIRO_MAXSHORT;
|
||||
extents->height = CAIRO_MAXSHORT;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -51,9 +51,6 @@
|
|||
* could add generation counters to surfaces and remember the stream
|
||||
* ID for a particular generation for a particular surface.
|
||||
*
|
||||
* - Multi stop gradients. What are the exponential interpolation
|
||||
* functions, could they be used for gradients?
|
||||
*
|
||||
* - Clipping: must be able to reset clipping
|
||||
*
|
||||
* - Images of other formats than 8 bit RGBA.
|
||||
|
@ -79,8 +76,6 @@
|
|||
*
|
||||
* - Add test case for RGBA gradients.
|
||||
*
|
||||
* - Pattern extend isn't honoured by image backend.
|
||||
*
|
||||
* - Coordinate space for create_similar() args?
|
||||
*
|
||||
* - Investigate /Matrix entry in content stream dicts for pages
|
||||
|
@ -194,10 +189,13 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend;
|
|||
static unsigned int
|
||||
_cairo_pdf_document_new_object (cairo_pdf_document_t *document)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pdf_object_t object;
|
||||
|
||||
object.offset = _cairo_output_stream_get_position (document->output_stream);
|
||||
if (_cairo_array_append (&document->objects, &object, 1) == NULL)
|
||||
|
||||
status = _cairo_array_append (&document->objects, &object);
|
||||
if (status)
|
||||
return 0;
|
||||
|
||||
return document->next_available_id++;
|
||||
|
@ -217,7 +215,8 @@ static void
|
|||
_cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_stream_t *stream)
|
||||
{
|
||||
_cairo_array_append (&surface->streams, &stream, 1);
|
||||
/* XXX: Should be checking the return value here. */
|
||||
_cairo_array_append (&surface->streams, &stream);
|
||||
surface->current_stream = stream;
|
||||
}
|
||||
|
||||
|
@ -227,7 +226,8 @@ _cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, unsigned int id)
|
|||
cairo_pdf_resource_t resource;
|
||||
|
||||
resource.id = id;
|
||||
_cairo_array_append (&surface->patterns, &resource, 1);
|
||||
/* XXX: Should be checking the return value here. */
|
||||
_cairo_array_append (&surface->patterns, &resource);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -244,7 +244,8 @@ _cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface, unsigned int id)
|
|||
}
|
||||
|
||||
resource.id = id;
|
||||
_cairo_array_append (&surface->xobjects, &resource, 1);
|
||||
/* XXX: Should be checking the return value here. */
|
||||
_cairo_array_append (&surface->xobjects, &resource);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
@ -260,7 +261,8 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
|
|||
return i;
|
||||
}
|
||||
|
||||
_cairo_array_append (&surface->alphas, &alpha, 1);
|
||||
/* XXX: Should be checking the return value here. */
|
||||
_cairo_array_append (&surface->alphas, &alpha);
|
||||
return _cairo_array_num_elements (&surface->alphas) - 1;
|
||||
}
|
||||
|
||||
|
@ -278,7 +280,8 @@ _cairo_pdf_surface_add_font (cairo_pdf_surface_t *surface, unsigned int id)
|
|||
}
|
||||
|
||||
resource.id = id;
|
||||
_cairo_array_append (&surface->fonts, &resource, 1);
|
||||
/* XXX: Should be checking the return value here. */
|
||||
_cairo_array_append (&surface->fonts, &resource);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
|
@ -710,7 +713,7 @@ _cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_composite (cairo_operator_t operator,
|
||||
_cairo_pdf_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -740,7 +743,7 @@ _cairo_pdf_surface_composite (cairo_operator_t operator,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -766,7 +769,7 @@ _cairo_pdf_surface_fill_rectangles (void *abstract_surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
emit_solid_pattern (cairo_pdf_surface_t *surface,
|
||||
cairo_solid_pattern_t *pattern)
|
||||
{
|
||||
|
@ -782,11 +785,13 @@ emit_solid_pattern (cairo_pdf_surface_t *surface,
|
|||
pattern->color.green,
|
||||
pattern->color.blue,
|
||||
alpha);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
emit_surface_pattern (cairo_pdf_surface_t *dst,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_pdf_document_t *document = dst->document;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
|
@ -797,13 +802,14 @@ emit_surface_pattern (cairo_pdf_surface_t *dst,
|
|||
unsigned int id, alpha;
|
||||
cairo_matrix_t pm;
|
||||
|
||||
if (pattern->surface->backend == &cairo_pdf_surface_backend) {
|
||||
return;
|
||||
}
|
||||
/* XXX: This is broken. We need new code here to actually emit the
|
||||
* PDF surface. */
|
||||
if (pattern->surface->backend == &cairo_pdf_surface_backend)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
|
||||
if (status)
|
||||
return;
|
||||
return status;
|
||||
|
||||
_cairo_pdf_document_close_stream (document);
|
||||
|
||||
|
@ -841,48 +847,155 @@ emit_surface_pattern (cairo_pdf_surface_t *dst,
|
|||
stream->id, alpha);
|
||||
|
||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _cairo_pdf_color_stop {
|
||||
double offset;
|
||||
unsigned int gradient_id;
|
||||
unsigned char color_char[4];
|
||||
} cairo_pdf_color_stop_t;
|
||||
|
||||
|
||||
static unsigned int
|
||||
emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
|
||||
emit_linear_colorgradient (cairo_pdf_document_t *document,
|
||||
cairo_pdf_color_stop_t *stop1,
|
||||
cairo_pdf_color_stop_t *stop2)
|
||||
{
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
unsigned int function_id;
|
||||
char stops[2][3];
|
||||
|
||||
function_id = _cairo_pdf_document_new_object (document);
|
||||
|
||||
unsigned int function_id = _cairo_pdf_document_new_object (document);
|
||||
|
||||
_cairo_output_stream_printf (output,
|
||||
"%d 0 obj\r\n"
|
||||
"<< /FunctionType 0\r\n"
|
||||
" /Domain [ 0.0 1.0 ]\r\n"
|
||||
" /Domain [ 0 1 ]\r\n"
|
||||
" /Size [ 2 ]\r\n"
|
||||
" /BitsPerSample 8\r\n"
|
||||
" /Range [ 0.0 1.0 0.0 1.0 0.0 1.0 ]\r\n"
|
||||
" /Range [ 0 1 0 1 0 1 ]\r\n"
|
||||
" /Length 6\r\n"
|
||||
">>\r\n"
|
||||
"stream\r\n",
|
||||
function_id);
|
||||
|
||||
stops[0][0] = pattern->stops[0].color.red * 0xff + 0.5;
|
||||
stops[0][1] = pattern->stops[0].color.green * 0xff + 0.5;
|
||||
stops[0][2] = pattern->stops[0].color.blue * 0xff + 0.5;
|
||||
stops[1][0] = pattern->stops[1].color.red * 0xff + 0.5;
|
||||
stops[1][1] = pattern->stops[1].color.green * 0xff + 0.5;
|
||||
stops[1][2] = pattern->stops[1].color.blue * 0xff + 0.5;
|
||||
|
||||
_cairo_output_stream_write (output, stops, sizeof (stops));
|
||||
|
||||
_cairo_output_stream_write (output, stop1->color_char, 3);
|
||||
_cairo_output_stream_write (output, stop2->color_char, 3);
|
||||
_cairo_output_stream_printf (output,
|
||||
"\r\n"
|
||||
"endstream\r\n"
|
||||
"endobj\r\n");
|
||||
|
||||
return function_id;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
emit_stiched_colorgradient (cairo_pdf_document_t *document,
|
||||
unsigned int n_stops,
|
||||
cairo_pdf_color_stop_t stops[])
|
||||
{
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
unsigned int function_id;
|
||||
unsigned int i;
|
||||
|
||||
/* emit linear gradients between pairs of subsequent stops... */
|
||||
for (i = 0; i < n_stops-1; i++) {
|
||||
stops[i].gradient_id = emit_linear_colorgradient (document,
|
||||
&stops[i],
|
||||
&stops[i+1]);
|
||||
}
|
||||
|
||||
/* ... and stich them together */
|
||||
function_id = _cairo_pdf_document_new_object (document);
|
||||
_cairo_output_stream_printf (output,
|
||||
"%d 0 obj\r\n"
|
||||
"<< /FunctionType 3\r\n"
|
||||
" /Domain [ 0 1 ]\r\n"
|
||||
" /Functions [ ",
|
||||
function_id);
|
||||
for (i = 0; i < n_stops-1; i++)
|
||||
_cairo_output_stream_printf (output, "%d 0 R ", stops[i].gradient_id);
|
||||
_cairo_output_stream_printf (output,
|
||||
"]\r\n"
|
||||
" /Bounds [ ");
|
||||
for (i = 1; i < n_stops-1; i++)
|
||||
_cairo_output_stream_printf (output, "%f ", stops[i].offset);
|
||||
_cairo_output_stream_printf (output,
|
||||
"]\r\n"
|
||||
" /Encode [ ");
|
||||
for (i = 1; i < n_stops; i++)
|
||||
_cairo_output_stream_printf (output, "0 1 ");
|
||||
_cairo_output_stream_printf (output,
|
||||
"]\r\n"
|
||||
">>\r\n"
|
||||
"endobj\r\n");
|
||||
|
||||
return function_id;
|
||||
}
|
||||
|
||||
static void
|
||||
#define COLOR_STOP_EPSILLON 1e-6
|
||||
|
||||
static unsigned int
|
||||
emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
|
||||
{
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
unsigned int function_id;
|
||||
cairo_pdf_color_stop_t *allstops, *stops;
|
||||
unsigned int n_stops;
|
||||
unsigned int i;
|
||||
|
||||
function_id = _cairo_pdf_document_new_object (document);
|
||||
|
||||
allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
|
||||
if (allstops == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
stops = &allstops[1];
|
||||
n_stops = pattern->n_stops;
|
||||
|
||||
for (i = 0; i < pattern->n_stops; i++) {
|
||||
stops[i].color_char[0] = pattern->stops[i].color.red >> 8;
|
||||
stops[i].color_char[1] = pattern->stops[i].color.green >> 8;
|
||||
stops[i].color_char[2] = pattern->stops[i].color.blue >> 8;
|
||||
stops[i].color_char[3] = pattern->stops[i].color.alpha >> 8;
|
||||
stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
|
||||
}
|
||||
|
||||
/* make sure first offset is 0.0 and last offset is 1.0. (Otherwise Acrobat
|
||||
* Reader chokes.) */
|
||||
if (stops[0].offset > COLOR_STOP_EPSILLON) {
|
||||
memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t));
|
||||
stops = allstops;
|
||||
stops[0].offset = 0.0;
|
||||
n_stops++;
|
||||
}
|
||||
if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILLON) {
|
||||
memcpy (&stops[n_stops],
|
||||
&stops[n_stops - 1],
|
||||
sizeof (cairo_pdf_color_stop_t));
|
||||
stops[n_stops].offset = 1.0;
|
||||
n_stops++;
|
||||
}
|
||||
|
||||
if (n_stops == 2) {
|
||||
/* no need for stiched function */
|
||||
function_id = emit_linear_colorgradient (document, &stops[0], &stops[1]);
|
||||
} else {
|
||||
/* multiple stops: stich. XXX possible optimization: regulary spaced
|
||||
* stops do not require stiching. XXX */
|
||||
function_id = emit_stiched_colorgradient (document,
|
||||
n_stops,
|
||||
stops);
|
||||
}
|
||||
|
||||
free (allstops);
|
||||
|
||||
return function_id;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern)
|
||||
{
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
|
@ -894,15 +1007,17 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *patte
|
|||
_cairo_pdf_document_close_stream (document);
|
||||
|
||||
function_id = emit_pattern_stops (surface, &pattern->base);
|
||||
if (function_id == 0)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
p2u = pattern->base.base.matrix;
|
||||
cairo_matrix_invert (&p2u);
|
||||
|
||||
x0 = pattern->point0.x;
|
||||
y0 = pattern->point0.y;
|
||||
x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);
|
||||
y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);
|
||||
cairo_matrix_transform_point (&p2u, &x0, &y0);
|
||||
x1 = pattern->point1.x;
|
||||
y1 = pattern->point1.y;
|
||||
x1 = _cairo_fixed_to_double (pattern->gradient.p2.x);
|
||||
y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);
|
||||
cairo_matrix_transform_point (&p2u, &x1, &y1);
|
||||
|
||||
pattern_id = _cairo_pdf_document_new_object (document);
|
||||
|
@ -934,9 +1049,11 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *patte
|
|||
_cairo_output_stream_printf (output,
|
||||
"/Pattern cs /res%d scn /a%d gs\r\n",
|
||||
pattern_id, alpha);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern)
|
||||
{
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
|
@ -948,17 +1065,19 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *patte
|
|||
_cairo_pdf_document_close_stream (document);
|
||||
|
||||
function_id = emit_pattern_stops (surface, &pattern->base);
|
||||
if (function_id == 0)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
p2u = pattern->base.base.matrix;
|
||||
cairo_matrix_invert (&p2u);
|
||||
|
||||
x0 = pattern->center0.x;
|
||||
y0 = pattern->center0.y;
|
||||
r0 = pattern->radius0;
|
||||
x0 = _cairo_fixed_to_double (pattern->gradient.inner.x);
|
||||
y0 = _cairo_fixed_to_double (pattern->gradient.inner.y);
|
||||
r0 = _cairo_fixed_to_double (pattern->gradient.inner.radius);
|
||||
cairo_matrix_transform_point (&p2u, &x0, &y0);
|
||||
x1 = pattern->center1.x;
|
||||
y1 = pattern->center1.y;
|
||||
r1 = pattern->radius1;
|
||||
x1 = _cairo_fixed_to_double (pattern->gradient.outer.x);
|
||||
y1 = _cairo_fixed_to_double (pattern->gradient.outer.y);
|
||||
r1 = _cairo_fixed_to_double (pattern->gradient.outer.radius);
|
||||
cairo_matrix_transform_point (&p2u, &x1, &y1);
|
||||
|
||||
/* FIXME: This is surely crack, but how should you scale a radius
|
||||
|
@ -1001,28 +1120,29 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *patte
|
|||
_cairo_output_stream_printf (output,
|
||||
"/Pattern cs /res%d scn /a%d gs\r\n",
|
||||
pattern_id, alpha);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
|
||||
{
|
||||
switch (pattern->type) {
|
||||
case CAIRO_PATTERN_SOLID:
|
||||
emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
|
||||
break;
|
||||
return emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
|
||||
|
||||
case CAIRO_PATTERN_SURFACE:
|
||||
emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
|
||||
break;
|
||||
return emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
|
||||
|
||||
case CAIRO_PATTERN_LINEAR:
|
||||
emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
|
||||
break;
|
||||
return emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern);
|
||||
|
||||
case CAIRO_PATTERN_RADIAL:
|
||||
emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
|
||||
break;
|
||||
return emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
static double
|
||||
|
@ -1108,20 +1228,23 @@ _cairo_pdf_path_close_path (void *closure)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance)
|
||||
_cairo_pdf_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_pdf_surface_t *surface = abstract_dst;
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
const char *pdf_operator;
|
||||
cairo_status_t status;
|
||||
pdf_path_info_t info;
|
||||
|
||||
emit_pattern (surface, pattern);
|
||||
status = emit_pattern (surface, pattern);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* After the above switch the current stream should belong to this
|
||||
* surface, so no need to _cairo_pdf_surface_ensure_stream() */
|
||||
|
@ -1158,7 +1281,7 @@ _cairo_pdf_surface_fill_path (cairo_operator_t operator,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
_cairo_pdf_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -1174,9 +1297,12 @@ _cairo_pdf_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
cairo_pdf_surface_t *surface = abstract_dst;
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
cairo_int_status_t status;
|
||||
int i;
|
||||
|
||||
emit_pattern (surface, pattern);
|
||||
status = emit_pattern (surface, pattern);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* After the above switch the current stream should belong to this
|
||||
* surface, so no need to _cairo_pdf_surface_ensure_stream() */
|
||||
|
@ -1253,6 +1379,7 @@ static cairo_font_subset_t *
|
|||
_cairo_pdf_document_get_font (cairo_pdf_document_t *document,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
cairo_font_subset_t *pdf_font;
|
||||
unsigned int num_fonts, i;
|
||||
|
@ -1279,7 +1406,8 @@ _cairo_pdf_document_get_font (cairo_pdf_document_t *document,
|
|||
|
||||
pdf_font->font_id = _cairo_pdf_document_new_object (document);
|
||||
|
||||
if (_cairo_array_append (&document->fonts, &pdf_font, 1) == NULL) {
|
||||
status = _cairo_array_append (&document->fonts, &pdf_font);
|
||||
if (status) {
|
||||
_cairo_font_subset_destroy (pdf_font);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1288,23 +1416,24 @@ _cairo_pdf_document_get_font (cairo_pdf_document_t *document,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_pdf_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
cairo_pdf_document_t *document = surface->document;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
cairo_font_subset_t *pdf_font;
|
||||
cairo_int_status_t status;
|
||||
int i, index;
|
||||
double det;
|
||||
|
||||
|
@ -1323,7 +1452,9 @@ _cairo_pdf_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (fabs (det) < 0.000001)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
emit_pattern (surface, pattern);
|
||||
status = emit_pattern (surface, pattern);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (output,
|
||||
"BT /res%u 1 Tf", pdf_font->font_id);
|
||||
|
@ -1432,9 +1563,20 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
|||
NULL, /* set_clip_region */
|
||||
_cairo_pdf_surface_intersect_clip_path,
|
||||
_cairo_pdf_surface_get_extents,
|
||||
_cairo_pdf_surface_show_glyphs,
|
||||
_cairo_pdf_surface_fill_path,
|
||||
_cairo_pdf_surface_get_font_options
|
||||
_cairo_pdf_surface_old_show_glyphs,
|
||||
_cairo_pdf_surface_get_font_options,
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
/* Here are the drawing functions */
|
||||
|
||||
NULL, /* paint */
|
||||
NULL, /* mask */
|
||||
NULL, /* stroke */
|
||||
_cairo_pdf_surface_fill,
|
||||
NULL /* show_glyphs */
|
||||
};
|
||||
|
||||
static cairo_pdf_document_t *
|
||||
|
@ -1747,6 +1889,7 @@ static cairo_status_t
|
|||
_cairo_pdf_document_add_page (cairo_pdf_document_t *document,
|
||||
cairo_pdf_surface_t *surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pdf_stream_t *stream;
|
||||
cairo_pdf_resource_t *res;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
|
@ -1852,7 +1995,9 @@ _cairo_pdf_document_add_page (cairo_pdf_document_t *document,
|
|||
">>\r\n"
|
||||
"endobj\r\n");
|
||||
|
||||
_cairo_array_append (&document->pages, &page_id, 1);
|
||||
status = _cairo_array_append (&document->pages, &page_id);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-gstate-private.h"
|
||||
|
||||
static int
|
||||
_cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix);
|
||||
|
||||
|
@ -59,35 +57,28 @@ _cairo_pen_init_empty (cairo_pen_t *pen)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
double radius,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm)
|
||||
{
|
||||
int i;
|
||||
int reflect;
|
||||
double det;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
/* XXX: It would be nice to notice that the pen is already properly constructed.
|
||||
However, this test would also have to account for possible changes in the transformation
|
||||
matrix.
|
||||
if (pen->radius == radius && pen->tolerance == tolerance)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
*/
|
||||
_cairo_pen_fini (pen);
|
||||
}
|
||||
|
||||
pen->radius = radius;
|
||||
pen->tolerance = gstate->tolerance;
|
||||
pen->tolerance = tolerance;
|
||||
|
||||
_cairo_matrix_compute_determinant (&gstate->ctm, &det);
|
||||
_cairo_matrix_compute_determinant (ctm, &det);
|
||||
if (det >= 0) {
|
||||
reflect = 0;
|
||||
} else {
|
||||
reflect = 1;
|
||||
}
|
||||
|
||||
pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance,
|
||||
pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
|
||||
radius,
|
||||
&gstate->ctm);
|
||||
ctm);
|
||||
|
||||
pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
|
@ -105,7 +96,7 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
|||
double dx = radius * cos (reflect ? -theta : theta);
|
||||
double dy = radius * sin (reflect ? -theta : theta);
|
||||
cairo_pen_vertex_t *v = &pen->vertices[i];
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
cairo_matrix_transform_distance (ctm, &dx, &dy);
|
||||
v->point.x = _cairo_fixed_from_double (dx);
|
||||
v->point.y = _cairo_fixed_from_double (dy);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
@ -105,8 +106,8 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
surface->base.device_x_scale = surface->x_dpi / 72.0;
|
||||
surface->base.device_y_scale = surface->y_dpi / 72.0;
|
||||
|
||||
surface->current_page = _cairo_meta_surface_create (width,
|
||||
height);
|
||||
surface->current_page = _cairo_meta_surface_create (width * surface->x_dpi / 72,
|
||||
height * surface->y_dpi / 72);
|
||||
if (surface->current_page->status) {
|
||||
free (surface);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -194,7 +195,7 @@ _cairo_ps_surface_finish (void *abstract_surface)
|
|||
/* Document header */
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%!PS-Adobe-3.0\n"
|
||||
"%%%%Creator: Cairo (http://cairographics.org)\n"
|
||||
"%%%%Creator: cairo (http://cairographics.org)\n"
|
||||
"%%%%CreationDate: %s"
|
||||
"%%%%Title: Some clever title\n"
|
||||
"%%%%Pages: %d\n"
|
||||
|
@ -247,82 +248,6 @@ _cairo_ps_surface_finish (void *abstract_surface)
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_dst;
|
||||
|
||||
return _cairo_surface_composite (operator,
|
||||
src_pattern,
|
||||
mask_pattern,
|
||||
surface->current_page,
|
||||
src_x,
|
||||
src_y,
|
||||
mask_x,
|
||||
mask_y,
|
||||
dst_x,
|
||||
dst_y,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_fill_rectangles (surface->current_page,
|
||||
operator,
|
||||
color,
|
||||
rects,
|
||||
num_rects);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
int x_src,
|
||||
int y_src,
|
||||
int x_dst,
|
||||
int y_dst,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_dst;
|
||||
|
||||
return _cairo_surface_composite_trapezoids (operator,
|
||||
pattern,
|
||||
surface->current_page,
|
||||
antialias,
|
||||
x_src,
|
||||
y_src,
|
||||
x_dst,
|
||||
y_dst,
|
||||
width,
|
||||
height,
|
||||
traps,
|
||||
num_traps);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_copy_page (void *abstract_surface)
|
||||
{
|
||||
|
@ -336,11 +261,15 @@ _cairo_ps_surface_copy_page (void *abstract_surface)
|
|||
static cairo_int_status_t
|
||||
_cairo_ps_surface_show_page (void *abstract_surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
_cairo_array_append (&surface->pages, &surface->current_page, 1);
|
||||
surface->current_page = _cairo_meta_surface_create (surface->width,
|
||||
surface->height);
|
||||
status = _cairo_array_append (&surface->pages, &surface->current_page);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
surface->current_page = _cairo_meta_surface_create (surface->width * surface->x_dpi / 72,
|
||||
surface->height * surface->y_dpi / 72);
|
||||
if (surface->current_page->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -386,6 +315,7 @@ static cairo_font_subset_t *
|
|||
_cairo_ps_surface_get_font (cairo_ps_surface_t *surface,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
cairo_font_subset_t *subset;
|
||||
unsigned int num_fonts, i;
|
||||
|
@ -409,7 +339,9 @@ _cairo_ps_surface_get_font (cairo_ps_surface_t *surface,
|
|||
return NULL;
|
||||
|
||||
subset->font_id = surface->fonts.num_elements;
|
||||
if (_cairo_array_append (&surface->fonts, &subset, 1) == NULL) {
|
||||
|
||||
status = _cairo_array_append (&surface->fonts, &subset);
|
||||
if (status) {
|
||||
_cairo_font_subset_destroy (subset);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -418,65 +350,95 @@ _cairo_ps_surface_get_font (cairo_ps_surface_t *surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_ps_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_font_subset_t *subset;
|
||||
int i;
|
||||
|
||||
/* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
|
||||
if (! _cairo_scaled_font_is_ft (scaled_font))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
/* Collect font subset info as we go. */
|
||||
subset = _cairo_ps_surface_get_font (surface, scaled_font);
|
||||
if (subset == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
_cairo_font_subset_use_glyph (subset, glyphs[i].index);
|
||||
|
||||
return _cairo_surface_show_glyphs (scaled_font,
|
||||
operator,
|
||||
pattern,
|
||||
surface->current_page,
|
||||
source_x,
|
||||
source_y,
|
||||
dest_x,
|
||||
dest_y,
|
||||
width,
|
||||
height,
|
||||
glyphs,
|
||||
num_glyphs);
|
||||
return _cairo_surface_paint (surface->current_page, op, source);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance)
|
||||
_cairo_ps_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_dst;
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_fill_path (operator,
|
||||
pattern,
|
||||
surface->current_page,
|
||||
path,
|
||||
fill_rule,
|
||||
tolerance);
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_mask (surface->current_page, op, source,
|
||||
mask);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_stroke (surface->current_page, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_fill (surface->current_page, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_show_glyphs (surface->current_page, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_ps_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_snapshot (surface->current_page);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||
|
@ -487,16 +449,30 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
|||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
_cairo_ps_surface_composite,
|
||||
_cairo_ps_surface_fill_rectangles,
|
||||
_cairo_ps_surface_composite_trapezoids,
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
_cairo_ps_surface_copy_page,
|
||||
_cairo_ps_surface_show_page,
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_ps_surface_intersect_clip_path,
|
||||
_cairo_ps_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
/* Here are the drawing functions */
|
||||
|
||||
_cairo_ps_surface_paint,
|
||||
_cairo_ps_surface_mask,
|
||||
_cairo_ps_surface_stroke,
|
||||
_cairo_ps_surface_fill,
|
||||
_cairo_ps_surface_show_glyphs,
|
||||
_cairo_ps_surface_fill_path
|
||||
|
||||
_cairo_ps_surface_snapshot
|
||||
};
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -572,57 +548,30 @@ _cairo_ps_surface_write_font_subsets (cairo_ps_surface_t *surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct _cairo_ps_fallback_area cairo_ps_fallback_area_t;
|
||||
struct _cairo_ps_fallback_area {
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
cairo_ps_fallback_area_t *next;
|
||||
};
|
||||
|
||||
typedef struct _ps_output_surface {
|
||||
cairo_surface_t base;
|
||||
cairo_ps_surface_t *parent;
|
||||
cairo_ps_fallback_area_t *fallback_areas;
|
||||
cairo_bool_t fallback;
|
||||
} ps_output_surface_t;
|
||||
|
||||
/*
|
||||
* XXX for now, just a page-wide boolean
|
||||
* Doing a better job is harder as it must
|
||||
* avoid rendering the same object in pieces
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_ps_output_add_fallback_area (ps_output_surface_t *surface,
|
||||
int x, int y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_ps_fallback_area_t *area;
|
||||
|
||||
/* FIXME: Do a better job here. Ideally, we would use a 32 bit
|
||||
* region type, but probably just computing bounding boxes would
|
||||
* also work fine. */
|
||||
|
||||
area = malloc (sizeof (cairo_ps_fallback_area_t));
|
||||
if (area == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
area->x = x;
|
||||
area->y = y;
|
||||
area->width = width;
|
||||
area->height = height;
|
||||
area->next = surface->fallback_areas;
|
||||
|
||||
surface->fallback_areas = area;
|
||||
|
||||
surface->fallback = TRUE;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_ps_output_finish (void *abstract_surface)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
cairo_ps_fallback_area_t *area, *next;
|
||||
|
||||
for (area = surface->fallback_areas; area != NULL; area = next) {
|
||||
next = area->next;
|
||||
free (area);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -642,24 +591,162 @@ color_is_translucent (const cairo_color_t *color)
|
|||
}
|
||||
|
||||
static cairo_bool_t
|
||||
pattern_is_translucent (cairo_pattern_t *abstract_pattern)
|
||||
format_is_translucent (cairo_format_t format)
|
||||
{
|
||||
cairo_pattern_union_t *pattern;
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
return TRUE;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
return FALSE;
|
||||
case CAIRO_FORMAT_A8:
|
||||
return TRUE;
|
||||
case CAIRO_FORMAT_A1:
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
surface_is_translucent (const cairo_surface_t *surface)
|
||||
{
|
||||
if (_cairo_surface_is_image (surface)) {
|
||||
const cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
return format_is_translucent (image_surface->format);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
gradient_is_translucent (const cairo_gradient_pattern_t *gradient)
|
||||
{
|
||||
return TRUE; /* XXX no gradient support */
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gradient->n_stops; i++)
|
||||
if (color_is_translucent (&gradient->stops[i].color))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
pattern_is_translucent (const cairo_pattern_t *abstract_pattern)
|
||||
{
|
||||
const cairo_pattern_union_t *pattern;
|
||||
|
||||
pattern = (cairo_pattern_union_t *) abstract_pattern;
|
||||
switch (pattern->base.type) {
|
||||
case CAIRO_PATTERN_SOLID:
|
||||
return color_is_translucent (&pattern->solid.color);
|
||||
case CAIRO_PATTERN_SURFACE:
|
||||
return surface_is_translucent (pattern->surface.surface);
|
||||
case CAIRO_PATTERN_LINEAR:
|
||||
case CAIRO_PATTERN_RADIAL:
|
||||
return FALSE;
|
||||
return gradient_is_translucent (&pattern->gradient.base);
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
operator_always_opaque (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
return TRUE;
|
||||
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return TRUE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
operator_always_translucent (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
color_operation_needs_fallback (cairo_operator_t op,
|
||||
const cairo_color_t *color)
|
||||
{
|
||||
if (operator_always_opaque (op))
|
||||
return FALSE;
|
||||
if (operator_always_translucent (op))
|
||||
return TRUE;
|
||||
return color_is_translucent (color);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
pattern_type_supported (const cairo_pattern_t *pattern)
|
||||
{
|
||||
if (pattern->type == CAIRO_PATTERN_SOLID)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
pattern_operation_needs_fallback (cairo_operator_t op,
|
||||
const cairo_pattern_t *pattern)
|
||||
{
|
||||
if (! pattern_type_supported (pattern))
|
||||
return TRUE;
|
||||
if (operator_always_opaque (op))
|
||||
return FALSE;
|
||||
if (operator_always_translucent (op))
|
||||
return TRUE;
|
||||
return pattern_is_translucent (pattern);
|
||||
}
|
||||
|
||||
/* PS Output - this section handles output of the parts of the meta
|
||||
* surface we can render natively in PS. */
|
||||
|
||||
|
@ -711,7 +798,12 @@ emit_image (cairo_ps_surface_t *surface,
|
|||
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
|
||||
|
||||
_cairo_surface_composite (CAIRO_OPERATOR_DEST_OVER,
|
||||
_cairo_surface_fill_rectangle (opaque,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
CAIRO_COLOR_WHITE,
|
||||
0, 0, image->width, image->height);
|
||||
|
||||
_cairo_surface_composite (CAIRO_OPERATOR_OVER,
|
||||
&pattern.base,
|
||||
NULL,
|
||||
opaque,
|
||||
|
@ -812,18 +904,21 @@ static void
|
|||
emit_surface_pattern (cairo_ps_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
/* XXX: NYI */
|
||||
}
|
||||
|
||||
static void
|
||||
emit_linear_pattern (cairo_ps_surface_t *surface,
|
||||
cairo_linear_pattern_t *pattern)
|
||||
{
|
||||
/* XXX: NYI */
|
||||
}
|
||||
|
||||
static void
|
||||
emit_radial_pattern (cairo_ps_surface_t *surface,
|
||||
cairo_radial_pattern_t *pattern)
|
||||
{
|
||||
/* XXX: NYI */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -854,7 +949,7 @@ emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
|
|||
|
||||
|
||||
static cairo_int_status_t
|
||||
_ps_output_composite (cairo_operator_t operator,
|
||||
_ps_output_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -874,6 +969,9 @@ _ps_output_composite (cairo_operator_t operator,
|
|||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (mask_pattern) {
|
||||
/* FIXME: Investigate how this can be done... we'll probably
|
||||
* need pixmap fallbacks for this, though. */
|
||||
|
@ -928,7 +1026,7 @@ bail:
|
|||
|
||||
static cairo_int_status_t
|
||||
_ps_output_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -938,10 +1036,13 @@ _ps_output_fill_rectangles (void *abstract_surface,
|
|||
cairo_solid_pattern_t solid;
|
||||
int i;
|
||||
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (!num_rects)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (color_is_translucent (color)) {
|
||||
if (color_operation_needs_fallback (op, color)) {
|
||||
int min_x = rects[0].x;
|
||||
int min_y = rects[0].y;
|
||||
int max_x = rects[0].x + rects[0].width;
|
||||
|
@ -986,7 +1087,7 @@ intersect (cairo_line_t *line, cairo_fixed_t y)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_ps_output_composite_trapezoids (cairo_operator_t operator,
|
||||
_ps_output_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -1003,7 +1104,10 @@ _ps_output_composite_trapezoids (cairo_operator_t operator,
|
|||
cairo_output_stream_t *stream = surface->parent->stream;
|
||||
int i;
|
||||
|
||||
if (pattern_is_translucent (pattern))
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, pattern))
|
||||
return _ps_output_add_fallback_area (surface, x_dst, y_dst, width, height);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
|
@ -1123,6 +1227,9 @@ _ps_output_intersect_clip_path (void *abstract_surface,
|
|||
ps_output_path_info_t info;
|
||||
const char *ps_operator;
|
||||
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"%% _ps_output_intersect_clip_path\n");
|
||||
|
||||
|
@ -1162,33 +1269,39 @@ _ps_output_intersect_clip_path (void *abstract_surface,
|
|||
|
||||
|
||||
static cairo_int_status_t
|
||||
_ps_output_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_ps_output_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->parent->stream;
|
||||
cairo_font_subset_t *subset;
|
||||
int i, subset_index;
|
||||
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
|
||||
if (! _cairo_scaled_font_is_ft (scaled_font))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (pattern_is_translucent (pattern))
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, pattern))
|
||||
return _ps_output_add_fallback_area (surface, dest_x, dest_y, width, height);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"%% _ps_output_show_glyphs\n");
|
||||
"%% _ps_output_old_show_glyphs\n");
|
||||
|
||||
emit_pattern (surface->parent, pattern);
|
||||
|
||||
|
@ -1223,29 +1336,103 @@ _ps_output_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: Just stubbing this out for now. Should be able to do much
|
||||
* better here. */
|
||||
static cairo_int_status_t
|
||||
_ps_output_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance)
|
||||
_ps_output_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_dst;
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
|
||||
/* XXX: Should be able to do much better here. */
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
}
|
||||
|
||||
/* XXX: Just stubbing this out for now. Should be able to do much
|
||||
* better here. */
|
||||
static cairo_int_status_t
|
||||
_ps_output_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
|
||||
/* XXX: Should be able to do much better here. */
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
}
|
||||
|
||||
/* XXX: Just stubbing this out for now. Should be able to do much
|
||||
* better here. */
|
||||
static cairo_int_status_t
|
||||
_ps_output_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
|
||||
/* XXX: Should be able to do much better here. */
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_ps_output_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->parent->stream;
|
||||
cairo_int_status_t status;
|
||||
ps_output_path_info_t info;
|
||||
const char *ps_operator;
|
||||
|
||||
if (pattern_is_translucent (pattern))
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
_cairo_output_stream_printf (stream,
|
||||
"%% _ps_output_fill_path\n");
|
||||
"%% _ps_output_fill\n");
|
||||
|
||||
emit_pattern (surface->parent, pattern);
|
||||
emit_pattern (surface->parent, source);
|
||||
|
||||
info.output_stream = stream;
|
||||
info.has_current_point = FALSE;
|
||||
|
@ -1275,6 +1462,31 @@ _ps_output_fill_path (cairo_operator_t operator,
|
|||
return status;
|
||||
}
|
||||
|
||||
/* XXX: Just stubbing this out for now. Should be able to do much
|
||||
* better here. */
|
||||
static cairo_int_status_t
|
||||
_ps_output_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
ps_output_surface_t *surface = abstract_surface;
|
||||
|
||||
if (pattern_operation_needs_fallback (op, source))
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
|
||||
/* XXX: Should be able to do much better here. */
|
||||
return _ps_output_add_fallback_area (surface,
|
||||
0, 0,
|
||||
surface->parent->width,
|
||||
surface->parent->height);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t ps_output_backend = {
|
||||
NULL, /* create_similar */
|
||||
_ps_output_finish,
|
||||
|
@ -1291,8 +1503,20 @@ static const cairo_surface_backend_t ps_output_backend = {
|
|||
NULL, /* set_clip_region */
|
||||
_ps_output_intersect_clip_path,
|
||||
NULL, /* get_extents */
|
||||
_ps_output_show_glyphs,
|
||||
_ps_output_fill_path
|
||||
_ps_output_old_show_glyphs,
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
/* Here are the drawing functions */
|
||||
|
||||
_ps_output_paint,
|
||||
_ps_output_mask,
|
||||
_ps_output_stroke,
|
||||
_ps_output_fill,
|
||||
_ps_output_show_glyphs
|
||||
};
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -1306,7 +1530,7 @@ _ps_output_render_fallbacks (cairo_surface_t *surface,
|
|||
int width, height;
|
||||
|
||||
ps_output = (ps_output_surface_t *) surface;
|
||||
if (ps_output->fallback_areas == NULL)
|
||||
if (! ps_output->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
width = ps_output->parent->width * ps_output->parent->x_dpi / 72;
|
||||
|
@ -1356,7 +1580,7 @@ _ps_output_surface_create (cairo_ps_surface_t *parent)
|
|||
|
||||
_cairo_surface_init (&ps_output->base, &ps_output_backend);
|
||||
ps_output->parent = parent;
|
||||
ps_output->fallback_areas = NULL;
|
||||
ps_output->fallback = FALSE;
|
||||
|
||||
return &ps_output->base;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Calum Robinson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Calum Robinson
|
||||
*
|
||||
* Contributor(s):
|
||||
* Calum Robinson <calumr@mac.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_QUARTZ_PRIVATE_H
|
||||
#define CAIRO_QUARTZ_PRIVATE_H
|
||||
|
||||
#include <cairoint.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
typedef struct cairo_quartz_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
CGContextRef context;
|
||||
|
||||
cairo_bool_t flipped;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
cairo_image_surface_t *image;
|
||||
pixman_region16_t *clip_region;
|
||||
|
||||
CGImageRef cgImage;
|
||||
} cairo_quartz_surface_t;
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_quartz (cairo_surface_t *surface);
|
||||
|
||||
#endif /* CAIRO_QUARTZ_PRIVATE_H */
|
|
@ -35,20 +35,7 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-private.h"
|
||||
#include "cairo-quartz.h"
|
||||
|
||||
typedef struct cairo_quartz_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
CGContextRef context;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
cairo_image_surface_t *image;
|
||||
|
||||
CGImageRef cgImage;
|
||||
} cairo_quartz_surface_t;
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
static void
|
||||
ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
||||
|
@ -69,6 +56,9 @@ _cairo_quartz_surface_finish(void *abstract_surface)
|
|||
if (surface->cgImage)
|
||||
CGImageRelease(surface->cgImage);
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -174,8 +164,17 @@ _cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
|||
|
||||
rect = CGRectMake(0, 0, surface->width, surface->height);
|
||||
|
||||
if (surface->flipped) {
|
||||
CGContextSaveGState (surface->context);
|
||||
CGContextTranslateCTM (surface->context, 0, surface->height);
|
||||
CGContextScaleCTM (surface->context, 1, -1);
|
||||
}
|
||||
|
||||
CGContextDrawImage(surface->context, rect, surface->cgImage);
|
||||
|
||||
if (surface->flipped)
|
||||
CGContextRestoreGState (surface->context);
|
||||
|
||||
memset(surface->image->data, 0, surface->width * surface->height * 4);
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +187,16 @@ _cairo_quartz_surface_set_clip_region(void *abstract_surface,
|
|||
unsigned int serial;
|
||||
|
||||
serial = _cairo_surface_allocate_clip_serial (&surface->image->base);
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (region) {
|
||||
surface->clip_region = pixman_region_create ();
|
||||
pixman_region_copy (surface->clip_region, region);
|
||||
} else
|
||||
surface->clip_region = NULL;
|
||||
|
||||
return _cairo_surface_set_clip_region(&surface->image->base,
|
||||
region, serial);
|
||||
}
|
||||
|
@ -222,11 +231,12 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
|||
_cairo_quartz_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_quartz_surface_get_extents,
|
||||
NULL /* show_glyphs */
|
||||
NULL /* old_show_glyphs */
|
||||
};
|
||||
|
||||
|
||||
cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
||||
cairo_bool_t flipped,
|
||||
int width, int height)
|
||||
{
|
||||
cairo_quartz_surface_t *surface;
|
||||
|
@ -244,6 +254,8 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
|||
surface->height = height;
|
||||
surface->image = NULL;
|
||||
surface->cgImage = NULL;
|
||||
surface->clip_region = NULL;
|
||||
surface->flipped = flipped;
|
||||
|
||||
// Set up the image surface which Cairo draws into and we blit to & from.
|
||||
void *foo;
|
||||
|
@ -251,3 +263,9 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
|||
|
||||
return (cairo_surface_t *) surface;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_surface_is_quartz (cairo_surface_t *surface)
|
||||
{
|
||||
return surface->backend == &cairo_quartz_surface_backend;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ CAIRO_BEGIN_DECLS
|
|||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_surface_create (CGContextRef context,
|
||||
cairo_bool_t flipped,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: cairo-scaled-font.c,v 1.1 2005-10-06 04:02:06 vladimir%pobox.com Exp $
|
||||
/* $Id: cairo-scaled-font.c,v 1.3 2006-01-18 22:15:25 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
|
@ -776,7 +776,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
|
@ -785,7 +785,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
@ -795,14 +795,14 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
/* These operators aren't interpreted the same way by the backends;
|
||||
* they are implemented in terms of other operators in cairo-gstate.c
|
||||
*/
|
||||
assert (operator != CAIRO_OPERATOR_SOURCE && operator != CAIRO_OPERATOR_CLEAR);
|
||||
assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
|
||||
|
||||
if (scaled_font->status)
|
||||
return scaled_font->status;
|
||||
|
||||
if (scaled_font->backend->show_glyphs != NULL) {
|
||||
status = scaled_font->backend->show_glyphs (scaled_font,
|
||||
operator, pattern,
|
||||
op, pattern,
|
||||
surface,
|
||||
source_x, source_y,
|
||||
dest_x, dest_y,
|
||||
|
@ -887,7 +887,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
_cairo_pattern_init_for_surface (&mask_pattern, mask);
|
||||
|
||||
status = _cairo_surface_composite (operator, pattern, &mask_pattern.base,
|
||||
status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
|
||||
surface,
|
||||
source_x, source_y,
|
||||
0, 0,
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
void
|
||||
_cairo_stroke_style_init (cairo_stroke_style_t *style)
|
||||
{
|
||||
style->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
|
||||
style->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT;
|
||||
style->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT;
|
||||
style->miter_limit = CAIRO_GSTATE_MITER_LIMIT_DEFAULT;
|
||||
|
||||
style->dash = NULL;
|
||||
style->num_dashes = 0;
|
||||
style->dash_offset = 0.0;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
||||
cairo_stroke_style_t *other)
|
||||
{
|
||||
style->line_width = other->line_width;
|
||||
style->line_cap = other->line_cap;
|
||||
style->line_join = other->line_join;
|
||||
style->miter_limit = other->miter_limit;
|
||||
|
||||
style->num_dashes = other->num_dashes;
|
||||
|
||||
if (other->dash == NULL) {
|
||||
style->dash = NULL;
|
||||
} else {
|
||||
style->dash = malloc (style->num_dashes * sizeof (double));
|
||||
if (style->dash == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
memcpy (style->dash, other->dash,
|
||||
style->num_dashes * sizeof (double));
|
||||
}
|
||||
|
||||
style->dash_offset = other->dash_offset;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_stroke_style_fini (cairo_stroke_style_t *style)
|
||||
{
|
||||
if (style->dash) {
|
||||
free (style->dash);
|
||||
style->dash = NULL;
|
||||
}
|
||||
style->num_dashes = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_SURFACE_FALLBACK_PRIVATE_H
|
||||
#define CAIRO_SURFACE_FALLBACK_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_paint (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_mask (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_fill (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_surface_fallback_snapshot (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_antialias_t antialias,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_trapezoid_t *traps,
|
||||
int num_traps);
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,63 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* cairo-svg.h
|
||||
*
|
||||
* Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_SVG_H
|
||||
#define CAIRO_SVG_H
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#if CAIRO_HAS_SVG_SURFACE
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_svg_surface_create (const char *filename,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
void *closure,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
void
|
||||
cairo_svg_surface_set_dpi (cairo_surface_t *surface,
|
||||
double x_dpi,
|
||||
double y_dpi);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_SVG_SURFACE */
|
||||
# error Cairo was not compiled with support for the svg backend
|
||||
#endif /* CAIRO_HAS_SVG_SURFACE */
|
||||
|
||||
#endif /* CAIRO_SVG_H */
|
|
@ -258,6 +258,54 @@ _cairo_traps_translate (cairo_traps_t *traps, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
|
||||
cairo_trapezoid_t *src_traps,
|
||||
int num_traps,
|
||||
double tx, double ty,
|
||||
double sx, double sy)
|
||||
{
|
||||
int i;
|
||||
cairo_fixed_t xoff = _cairo_fixed_from_double (tx);
|
||||
cairo_fixed_t yoff = _cairo_fixed_from_double (ty);
|
||||
|
||||
if (sx == 1.0 && sy == 1.0) {
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = src_traps[i].top + yoff;
|
||||
offset_traps[i].bottom = src_traps[i].bottom + yoff;
|
||||
offset_traps[i].left.p1.x = src_traps[i].left.p1.x + xoff;
|
||||
offset_traps[i].left.p1.y = src_traps[i].left.p1.y + yoff;
|
||||
offset_traps[i].left.p2.x = src_traps[i].left.p2.x + xoff;
|
||||
offset_traps[i].left.p2.y = src_traps[i].left.p2.y + yoff;
|
||||
offset_traps[i].right.p1.x = src_traps[i].right.p1.x + xoff;
|
||||
offset_traps[i].right.p1.y = src_traps[i].right.p1.y + yoff;
|
||||
offset_traps[i].right.p2.x = src_traps[i].right.p2.x + xoff;
|
||||
offset_traps[i].right.p2.y = src_traps[i].right.p2.y + yoff;
|
||||
}
|
||||
} else {
|
||||
cairo_fixed_t xsc = _cairo_fixed_from_double (sx);
|
||||
cairo_fixed_t ysc = _cairo_fixed_from_double (sy);
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
#define FIXED_MUL(_a, _b) \
|
||||
(_cairo_int64_to_int32(_cairo_int64_rsl(_cairo_int32x32_64_mul((_a), (_b)), 16)))
|
||||
|
||||
offset_traps[i].top = FIXED_MUL(src_traps[i].top + yoff, ysc);
|
||||
offset_traps[i].bottom = FIXED_MUL(src_traps[i].bottom + yoff, ysc);
|
||||
offset_traps[i].left.p1.x = FIXED_MUL(src_traps[i].left.p1.x + xoff, xsc);
|
||||
offset_traps[i].left.p1.y = FIXED_MUL(src_traps[i].left.p1.y + yoff, ysc);
|
||||
offset_traps[i].left.p2.x = FIXED_MUL(src_traps[i].left.p2.x + xoff, xsc);
|
||||
offset_traps[i].left.p2.y = FIXED_MUL(src_traps[i].left.p2.y + yoff, ysc);
|
||||
offset_traps[i].right.p1.x = FIXED_MUL(src_traps[i].right.p1.x + xoff, xsc);
|
||||
offset_traps[i].right.p1.y = FIXED_MUL(src_traps[i].right.p1.y + yoff, ysc);
|
||||
offset_traps[i].right.p2.x = FIXED_MUL(src_traps[i].right.p2.x + xoff, xsc);
|
||||
offset_traps[i].right.p2.y = FIXED_MUL(src_traps[i].right.p2.y + yoff, ysc);
|
||||
|
||||
#undef FIXED_MUL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
|
||||
{
|
||||
|
@ -859,4 +907,3 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -891,15 +891,20 @@ _start_glyphs (cairo_glyph_state_t *state,
|
|||
static cairo_status_t
|
||||
_flush_glyphs (cairo_glyph_state_t *state)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int dx = 0;
|
||||
if (!_cairo_array_append (&state->dx, &dx, 1))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
WCHAR * elements;
|
||||
|
||||
status = _cairo_array_append (&state->dx, &dx);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
elements = _cairo_array_index (&state->glyphs, 0);
|
||||
if (!ExtTextOutW (state->hdc,
|
||||
state->start_x, state->last_y,
|
||||
ETO_GLYPH_INDEX,
|
||||
NULL,
|
||||
(WCHAR *)state->glyphs.elements,
|
||||
elements,
|
||||
state->glyphs.num_elements,
|
||||
(int *)state->dx.elements)) {
|
||||
return _cairo_win32_print_gdi_error ("_flush_glyphs");
|
||||
|
@ -917,6 +922,7 @@ _add_glyph (cairo_glyph_state_t *state,
|
|||
double device_x,
|
||||
double device_y)
|
||||
{
|
||||
cairo_status_t status;
|
||||
double user_x = device_x;
|
||||
double user_y = device_y;
|
||||
WCHAR glyph_index = index;
|
||||
|
@ -931,15 +937,16 @@ _add_glyph (cairo_glyph_state_t *state,
|
|||
int dx;
|
||||
|
||||
if (logical_y != state->last_y) {
|
||||
cairo_status_t status = _flush_glyphs (state);
|
||||
status = _flush_glyphs (state);
|
||||
if (status)
|
||||
return status;
|
||||
state->start_x = logical_x;
|
||||
}
|
||||
|
||||
dx = logical_x - state->last_x;
|
||||
if (!_cairo_array_append (&state->dx, &dx, 1))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_array_append (&state->dx, &dx);
|
||||
if (status)
|
||||
return status;
|
||||
} else {
|
||||
state->start_x = logical_x;
|
||||
}
|
||||
|
@ -947,7 +954,9 @@ _add_glyph (cairo_glyph_state_t *state,
|
|||
state->last_x = logical_x;
|
||||
state->last_y = logical_y;
|
||||
|
||||
_cairo_array_append (&state->glyphs, &glyph_index, 1);
|
||||
status = _cairo_array_append (&state->glyphs, &glyph_index);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1096,7 +1105,7 @@ _cairo_win32_scaled_font_glyph_init (void *abstract_font,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_surface,
|
||||
int source_x,
|
||||
|
@ -1117,7 +1126,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
|||
|
||||
if (_cairo_surface_is_win32 (generic_surface) &&
|
||||
surface->format == CAIRO_FORMAT_RGB24 &&
|
||||
operator == CAIRO_OPERATOR_OVER &&
|
||||
op == CAIRO_OPERATOR_OVER &&
|
||||
_cairo_pattern_is_opaque_solid (pattern)) {
|
||||
|
||||
cairo_solid_pattern_t *solid_pattern = (cairo_solid_pattern_t *)pattern;
|
||||
|
@ -1186,13 +1195,13 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* For operator == OVER, no-cleartype, a possible optimization here is to
|
||||
/* For op == OVER, no-cleartype, a possible optimization here is to
|
||||
* draw onto an intermediate ARGB32 surface and alpha-blend that with the
|
||||
* destination
|
||||
*/
|
||||
_cairo_pattern_init_for_surface (&mask, mask_surface);
|
||||
|
||||
status = _cairo_surface_composite (operator, pattern,
|
||||
status = _cairo_surface_composite (op, pattern,
|
||||
&mask.base,
|
||||
&surface->base,
|
||||
source_x, source_y,
|
||||
|
|
|
@ -614,7 +614,7 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_surface_composite (cairo_operator_t operator,
|
||||
_cairo_win32_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -662,8 +662,8 @@ _cairo_win32_surface_composite (cairo_operator_t operator,
|
|||
|
||||
if (alpha == 255 &&
|
||||
src->format == dst->format &&
|
||||
(operator == CAIRO_OPERATOR_SOURCE ||
|
||||
(src->format == CAIRO_FORMAT_RGB24 && operator == CAIRO_OPERATOR_OVER))) {
|
||||
(op == CAIRO_OPERATOR_SOURCE ||
|
||||
(src->format == CAIRO_FORMAT_RGB24 && op == CAIRO_OPERATOR_OVER))) {
|
||||
|
||||
if (!BitBlt (dst->dc,
|
||||
dst_x, dst_y,
|
||||
|
@ -678,7 +678,7 @@ _cairo_win32_surface_composite (cairo_operator_t operator,
|
|||
} else if (integer_transform &&
|
||||
(src->format == CAIRO_FORMAT_RGB24 || src->format == CAIRO_FORMAT_ARGB32) &&
|
||||
dst->format == CAIRO_FORMAT_RGB24 &&
|
||||
operator == CAIRO_OPERATOR_OVER) {
|
||||
op == CAIRO_OPERATOR_OVER) {
|
||||
|
||||
return _composite_alpha_blend (dst, src, alpha,
|
||||
src_x + itx, src_y + ity,
|
||||
|
@ -695,7 +695,7 @@ _cairo_win32_surface_composite (cairo_operator_t operator,
|
|||
* super-luminescent colors (a == 0, r,g,b > 0)
|
||||
*/
|
||||
static enum { DO_CLEAR, DO_SOURCE, DO_NOTHING, DO_UNSUPPORTED }
|
||||
categorize_solid_dest_operator (cairo_operator_t operator,
|
||||
categorize_solid_dest_operator (cairo_operator_t op,
|
||||
unsigned short alpha)
|
||||
{
|
||||
enum { SOURCE_TRANSPARENT, SOURCE_LIGHT, SOURCE_SOLID, SOURCE_OTHER } source;
|
||||
|
@ -707,7 +707,7 @@ categorize_solid_dest_operator (cairo_operator_t operator,
|
|||
else
|
||||
source = SOURCE_OTHER;
|
||||
|
||||
switch (operator) {
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR: /* 0 0 */
|
||||
case CAIRO_OPERATOR_OUT: /* 1 - Ab 0 */
|
||||
return DO_CLEAR;
|
||||
|
@ -768,7 +768,7 @@ categorize_solid_dest_operator (cairo_operator_t operator,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -788,7 +788,7 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
|||
/* Optimize for no destination alpha (surface->pixman_image is non-NULL for all
|
||||
* surfaces with alpha.)
|
||||
*/
|
||||
switch (categorize_solid_dest_operator (operator, color->alpha_short)) {
|
||||
switch (categorize_solid_dest_operator (op, color->alpha_short)) {
|
||||
case DO_CLEAR:
|
||||
new_color = RGB (0, 0, 0);
|
||||
break;
|
||||
|
@ -837,10 +837,6 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
#if 0
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
#endif
|
||||
|
||||
/* If we are in-memory, then we set the clip on the image surface
|
||||
* as well as on the underlying GDI surface.
|
||||
*/
|
||||
|
@ -1049,8 +1045,7 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
|||
_cairo_win32_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_win32_surface_get_extents,
|
||||
NULL, /* show_glyphs */
|
||||
NULL, /* fill_path */
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
_cairo_win32_surface_flush,
|
||||
NULL /* mark_dirty_rectangle */
|
||||
|
@ -1067,7 +1062,6 @@ CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex;
|
|||
CRITICAL_SECTION cairo_scaled_font_map_mutex;
|
||||
CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex;
|
||||
|
||||
#if 0
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE hinstDLL,
|
||||
DWORD fdwReason,
|
||||
|
@ -1090,5 +1084,3 @@ DllMain (HINSTANCE hinstDLL,
|
|||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -787,6 +787,8 @@ _cairo_xcb_surface_set_attributes (cairo_xcb_surface_t *surface,
|
|||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
status = _cairo_xcb_surface_set_filter (surface, attributes->filter);
|
||||
|
@ -797,9 +799,9 @@ _cairo_xcb_surface_set_attributes (cairo_xcb_surface_t *surface,
|
|||
}
|
||||
|
||||
static int
|
||||
_render_operator (cairo_operator_t operator)
|
||||
_render_operator (cairo_operator_t op)
|
||||
{
|
||||
switch (operator) {
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return XCBRenderPictOpClear;
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
|
@ -834,7 +836,7 @@ _render_operator (cairo_operator_t operator)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_composite (cairo_operator_t operator,
|
||||
_cairo_xcb_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -875,7 +877,7 @@ _cairo_xcb_surface_composite (cairo_operator_t operator,
|
|||
status = _cairo_xcb_surface_set_attributes (mask, &mask_attr);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
XCBRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->picture,
|
||||
mask->picture,
|
||||
dst->picture,
|
||||
|
@ -891,7 +893,7 @@ _cairo_xcb_surface_composite (cairo_operator_t operator,
|
|||
static XCBRenderPICTURE maskpict = { 0 };
|
||||
|
||||
XCBRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->picture,
|
||||
maskpict,
|
||||
dst->picture,
|
||||
|
@ -913,7 +915,7 @@ _cairo_xcb_surface_composite (cairo_operator_t operator,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -931,7 +933,7 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
|||
|
||||
/* XXX: This XCBRECTANGLE cast is evil... it needs to go away somehow. */
|
||||
XCBRenderFillRectangles (surface->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
surface->picture,
|
||||
render_color, num_rects, (XCBRECTANGLE *) rects);
|
||||
|
||||
|
@ -939,7 +941,7 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
_cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -995,7 +997,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
XCBRenderTrapezoids (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->picture, dst->picture,
|
||||
render_format.id,
|
||||
render_src_x + attributes.x_offset,
|
||||
|
@ -1038,7 +1040,12 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
|||
NULL, /* _cairo_xcb_surface_set_clip_region */
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_xcb_surface_get_extents,
|
||||
NULL /* show_glyphs */
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL /* scaled_glyph_fini */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -693,6 +693,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
|
|||
ximage.red_mask = red;
|
||||
ximage.green_mask = green;
|
||||
ximage.blue_mask = blue;
|
||||
ximage.xoffset = 0;
|
||||
|
||||
XInitImage (&ximage);
|
||||
|
||||
|
@ -936,6 +937,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface,
|
|||
_cairo_xlib_surface_set_repeat (surface, 1);
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
case CAIRO_EXTEND_PAD:
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -993,14 +995,14 @@ _surface_has_alpha (cairo_xlib_surface_t *surface)
|
|||
* requires alpha compositing to complete.
|
||||
*/
|
||||
static cairo_bool_t
|
||||
_operator_needs_alpha_composite (cairo_operator_t operator,
|
||||
_operator_needs_alpha_composite (cairo_operator_t op,
|
||||
cairo_bool_t surface_has_alpha)
|
||||
{
|
||||
if (operator == CAIRO_OPERATOR_SOURCE ||
|
||||
if (op == CAIRO_OPERATOR_SOURCE ||
|
||||
(!surface_has_alpha &&
|
||||
(operator == CAIRO_OPERATOR_OVER ||
|
||||
operator == CAIRO_OPERATOR_ATOP ||
|
||||
operator == CAIRO_OPERATOR_IN)))
|
||||
(op == CAIRO_OPERATOR_OVER ||
|
||||
op == CAIRO_OPERATOR_ATOP ||
|
||||
op == CAIRO_OPERATOR_IN)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1037,7 +1039,7 @@ typedef enum {
|
|||
*/
|
||||
static composite_operation_t
|
||||
_categorize_composite_operation (cairo_xlib_surface_t *dst,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_bool_t have_mask)
|
||||
|
||||
|
@ -1058,13 +1060,13 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst,
|
|||
* fallback is impossible.
|
||||
*/
|
||||
if (have_mask ||
|
||||
!(operator == CAIRO_OPERATOR_SOURCE || operator == CAIRO_OPERATOR_OVER))
|
||||
!(op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER))
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
if (_cairo_surface_is_xlib (surface_pattern->surface)) {
|
||||
cairo_xlib_surface_t *src = (cairo_xlib_surface_t *)surface_pattern->surface;
|
||||
|
||||
if (operator == CAIRO_OPERATOR_OVER && _surface_has_alpha (src))
|
||||
if (op == CAIRO_OPERATOR_OVER && _surface_has_alpha (src))
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
/* If these are on the same screen but otherwise incompatible,
|
||||
|
@ -1097,7 +1099,7 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst,
|
|||
*/
|
||||
static composite_operation_t
|
||||
_recategorize_composite_operation (cairo_xlib_surface_t *dst,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_surface_attributes_t *src_attr,
|
||||
cairo_bool_t have_mask)
|
||||
|
@ -1105,7 +1107,7 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst,
|
|||
cairo_bool_t is_integer_translation =
|
||||
_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL);
|
||||
cairo_bool_t needs_alpha_composite =
|
||||
_operator_needs_alpha_composite (operator, _surface_has_alpha (src));
|
||||
_operator_needs_alpha_composite (op, _surface_has_alpha (src));
|
||||
|
||||
if (!have_mask &&
|
||||
is_integer_translation &&
|
||||
|
@ -1137,9 +1139,9 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst,
|
|||
}
|
||||
|
||||
static int
|
||||
_render_operator (cairo_operator_t operator)
|
||||
_render_operator (cairo_operator_t op)
|
||||
{
|
||||
switch (operator) {
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return PictOpClear;
|
||||
|
||||
|
@ -1177,7 +1179,7 @@ _render_operator (cairo_operator_t operator)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_composite (cairo_operator_t operator,
|
||||
_cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
|
@ -1201,7 +1203,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
operation = _categorize_composite_operation (dst, operator, src_pattern,
|
||||
operation = _categorize_composite_operation (dst, op, src_pattern,
|
||||
mask_pattern != NULL);
|
||||
if (operation == DO_UNSUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
@ -1217,7 +1219,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
operation = _recategorize_composite_operation (dst, operator, src, &src_attr,
|
||||
operation = _recategorize_composite_operation (dst, op, src, &src_attr,
|
||||
mask_pattern != NULL);
|
||||
if (operation == DO_UNSUPPORTED) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
@ -1238,7 +1240,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
goto FAIL;
|
||||
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
mask->src_picture,
|
||||
dst->dst_picture,
|
||||
|
@ -1250,7 +1252,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
width, height);
|
||||
} else {
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
0,
|
||||
dst->dst_picture,
|
||||
|
@ -1300,9 +1302,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
if (!_cairo_operator_bounded (operator) ||
|
||||
operator == CAIRO_OPERATOR_SOURCE ||
|
||||
operator == CAIRO_OPERATOR_CLEAR)
|
||||
if (!_cairo_operator_bounded_by_source (op))
|
||||
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
|
||||
&src_attr, src->width, src->height,
|
||||
mask ? &mask_attr : NULL,
|
||||
|
@ -1324,7 +1324,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
|
@ -1343,7 +1343,7 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface,
|
|||
/* XXX: This XRectangle cast is evil... it needs to go away somehow. */
|
||||
_cairo_xlib_surface_ensure_dst_picture (surface);
|
||||
XRenderFillRectangles (surface->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
surface->dst_picture,
|
||||
&render_color, (XRectangle *) rects, num_rects);
|
||||
|
||||
|
@ -1442,7 +1442,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
_cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -1467,7 +1467,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
operation = _categorize_composite_operation (dst, operator, pattern, TRUE);
|
||||
operation = _categorize_composite_operation (dst, op, pattern, TRUE);
|
||||
if (operation == DO_UNSUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
@ -1478,7 +1478,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
operation = _recategorize_composite_operation (dst, operator, src, &attributes, TRUE);
|
||||
operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
|
||||
if (operation == DO_UNSUPPORTED) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
goto FAIL;
|
||||
|
@ -1509,7 +1509,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
if (!_cairo_operator_bounded (operator)) {
|
||||
if (!_cairo_operator_bounded_by_mask (op)) {
|
||||
/* XRenderCompositeTrapezoids() creates a mask only large enough for the
|
||||
* trapezoids themselves, but if the operator is unbounded, then we need
|
||||
* to actually composite all the way out to the bounds, so we create
|
||||
|
@ -1528,7 +1528,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
}
|
||||
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
mask_picture,
|
||||
dst->dst_picture,
|
||||
|
@ -1551,7 +1551,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
} else {
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
XRenderCompositeTrapezoids (dst->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture, dst->dst_picture,
|
||||
pict_format,
|
||||
render_src_x + attributes.x_offset,
|
||||
|
@ -1654,18 +1654,18 @@ _cairo_xlib_surface_get_font_options (void *abstract_surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
|
||||
|
@ -1690,8 +1690,7 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
|
|||
_cairo_xlib_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_xlib_surface_get_extents,
|
||||
_cairo_xlib_surface_show_glyphs,
|
||||
NULL, /* fill_path */
|
||||
_cairo_xlib_surface_old_show_glyphs,
|
||||
_cairo_xlib_surface_get_font_options,
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
|
@ -2201,14 +2200,14 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
|||
#define N_STACK_BUF 1024
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_show_glyphs8 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
|
||||
XGlyphElt8 *elts = NULL;
|
||||
|
@ -2248,7 +2247,7 @@ _cairo_xlib_surface_show_glyphs8 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
XRenderCompositeText8 (self->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
self->dst_picture,
|
||||
font_private->format,
|
||||
|
@ -2263,14 +2262,14 @@ _cairo_xlib_surface_show_glyphs8 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_show_glyphs16 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
|
||||
XGlyphElt16 *elts = NULL;
|
||||
|
@ -2310,7 +2309,7 @@ _cairo_xlib_surface_show_glyphs16 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
XRenderCompositeText16 (self->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
self->dst_picture,
|
||||
font_private->format,
|
||||
|
@ -2325,14 +2324,14 @@ _cairo_xlib_surface_show_glyphs16 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_show_glyphs32 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_xlib_surface_t *src,
|
||||
cairo_xlib_surface_t *self,
|
||||
int source_x,
|
||||
int source_y,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
|
||||
XGlyphElt32 *elts = NULL;
|
||||
|
@ -2372,7 +2371,7 @@ _cairo_xlib_surface_show_glyphs32 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
XRenderCompositeText32 (self->dpy,
|
||||
_render_operator (operator),
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
self->dst_picture,
|
||||
font_private->format,
|
||||
|
@ -2387,18 +2386,18 @@ _cairo_xlib_surface_show_glyphs32 (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_surface_attributes_t attributes;
|
||||
cairo_int_status_t status;
|
||||
|
@ -2414,7 +2413,7 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
operation = _categorize_composite_operation (self, operator, pattern, TRUE);
|
||||
operation = _categorize_composite_operation (self, op, pattern, TRUE);
|
||||
if (operation == DO_UNSUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
@ -2431,7 +2430,7 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
operation = _recategorize_composite_operation (self, operator, src, &attributes, TRUE);
|
||||
operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE);
|
||||
if (operation == DO_UNSUPPORTED) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
goto FAIL;
|
||||
|
@ -2461,22 +2460,22 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
/* Call the appropriate sub-function. */
|
||||
|
||||
if (max_index < 256)
|
||||
status = _cairo_xlib_surface_show_glyphs8 (scaled_font, operator, src, self,
|
||||
status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
else if (max_index < 65536)
|
||||
status = _cairo_xlib_surface_show_glyphs16 (scaled_font, operator, src, self,
|
||||
status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
else
|
||||
status = _cairo_xlib_surface_show_glyphs32 (scaled_font, operator, src, self,
|
||||
status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded (operator)) {
|
||||
if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_rectangle_t extents;
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs,
|
||||
|
|
|
@ -82,8 +82,6 @@ static const cairo_t cairo_nil = {
|
|||
void
|
||||
_cairo_error (cairo_status_t status)
|
||||
{
|
||||
fprintf (stderr, "#### Cairo Error: %d\n", status);
|
||||
|
||||
assert (status > CAIRO_STATUS_SUCCESS &&
|
||||
status <= CAIRO_STATUS_LAST_STATUS);
|
||||
}
|
||||
|
@ -327,7 +325,7 @@ cairo_restore (cairo_t *cr)
|
|||
slim_hidden_def(cairo_restore);
|
||||
|
||||
/**
|
||||
* cairo_set_target:
|
||||
* moz_cairo_set_target:
|
||||
* @cr: a #cairo_t
|
||||
* @target: a #cairo_surface_t
|
||||
*
|
||||
|
@ -335,7 +333,7 @@ slim_hidden_def(cairo_restore);
|
|||
* @target must not be %NULL, or an error will be set on @cr.
|
||||
*/
|
||||
void
|
||||
cairo_set_target (cairo_t *cr, cairo_surface_t *target)
|
||||
moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
@ -345,36 +343,123 @@ cairo_set_target (cairo_t *cr, cairo_surface_t *target)
|
|||
return;
|
||||
}
|
||||
|
||||
_cairo_gstate_set_target (cr->gstate, target);
|
||||
_moz_cairo_gstate_set_target (cr->gstate, target);
|
||||
}
|
||||
slim_hidden_def(moz_cairo_set_target);
|
||||
|
||||
/**
|
||||
* cairo_push_group:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Pushes a temporary surface onto the rendering stack, redirecting
|
||||
* all rendering into it. The surface dimensions are the size of
|
||||
* the current clipping bounding box. Initially, this surface
|
||||
* is cleared to fully transparent black (0,0,0,1).
|
||||
*
|
||||
* cairo_push_group() calls cairo_save() so that any changes to the
|
||||
* graphics state will not be visible after cairo_pop_group() or
|
||||
* cairo_pop_group_with_alpha(). See cairo_pop_group() and
|
||||
* cairo_pop_group_with_alpha().
|
||||
*/
|
||||
|
||||
/* XXX: I want to rethink this API
|
||||
void
|
||||
cairo_push_group (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_surface_t *group_surface = NULL;
|
||||
|
||||
cr->status = cairoPush (cr);
|
||||
if (cr->status)
|
||||
return;
|
||||
/* Get the extents that we'll use in creating our new group surface */
|
||||
_cairo_surface_get_extents (_cairo_gstate_get_target (cr->gstate), &extents);
|
||||
status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
goto bail;
|
||||
|
||||
cr->status = _cairo_gstate_begin_group (cr->gstate);
|
||||
group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
extents.width,
|
||||
extents.height);
|
||||
status = cairo_surface_status (group_surface);
|
||||
if (status)
|
||||
goto bail;
|
||||
|
||||
/* XXX hrm. How best to make sure that drawing still happens in
|
||||
* the right place? Is this correct? Need to double-check the
|
||||
* coordinate spaces.
|
||||
*/
|
||||
cairo_surface_set_device_offset (group_surface, -extents.x, -extents.y);
|
||||
|
||||
/* create a new gstate for the redirect */
|
||||
cairo_save (cr);
|
||||
if (cr->status)
|
||||
goto bail;
|
||||
|
||||
_cairo_gstate_redirect_target (cr->gstate, group_surface);
|
||||
|
||||
bail:
|
||||
cairo_surface_destroy (group_surface);
|
||||
if (status)
|
||||
_cairo_set_error (cr, status);
|
||||
}
|
||||
slim_hidden_def(cairo_push_group);
|
||||
|
||||
void
|
||||
cairo_pattern_t *
|
||||
cairo_pop_group (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
cairo_surface_t *group_surface, *parent_target;
|
||||
cairo_pattern_t *group_pattern = NULL;
|
||||
|
||||
cr->status = _cairo_gstate_end_group (cr->gstate);
|
||||
if (cr->status)
|
||||
return;
|
||||
/* Grab the active surfaces */
|
||||
group_surface = _cairo_gstate_get_target (cr->gstate);
|
||||
parent_target = _cairo_gstate_get_parent_target (cr->gstate);
|
||||
|
||||
cr->status = cairoPop (cr);
|
||||
/* Verify that we are at the right nesting level */
|
||||
if (parent_target == NULL) {
|
||||
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We need to save group_surface before we restore; we don't need
|
||||
* to reference parent_target and original_target, since the
|
||||
* gstate will still hold refs to them once we restore. */
|
||||
cairo_surface_reference (group_surface);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
if (cr->status)
|
||||
goto done;
|
||||
|
||||
/* Undo the device offset we used; we're back in a normal-sized
|
||||
* surface, so this pattern will be positioned at the right place.
|
||||
* XXXvlad - er, this doesn't make sense, why does it work?
|
||||
*/
|
||||
cairo_surface_set_device_offset (group_surface, 0, 0);
|
||||
|
||||
group_pattern = cairo_pattern_create_for_surface (group_surface);
|
||||
if (!group_pattern) {
|
||||
cr->status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
cairo_surface_destroy (group_surface);
|
||||
|
||||
return group_pattern;
|
||||
}
|
||||
*/
|
||||
slim_hidden_def(cairo_pop_group);
|
||||
|
||||
void
|
||||
cairo_pop_group_to_source (cairo_t *cr)
|
||||
{
|
||||
cairo_pattern_t *group_pattern;
|
||||
|
||||
group_pattern = cairo_pop_group (cr);
|
||||
if (!group_pattern)
|
||||
return;
|
||||
|
||||
cairo_set_source (cr, group_pattern);
|
||||
}
|
||||
slim_hidden_def(cairo_pop_group_to_source);
|
||||
|
||||
/**
|
||||
* cairo_set_operator:
|
||||
|
@ -2422,7 +2507,7 @@ cairo_get_target (cairo_t *cr)
|
|||
if (cr->status)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
return _cairo_gstate_get_target (cr->gstate);
|
||||
return _cairo_gstate_get_original_target (cr->gstate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2433,10 +2518,6 @@ cairo_get_target (cairo_t *cr)
|
|||
* #cairo_path_t. See #cairo_path_data_t for hints on how to iterate
|
||||
* over the returned data structure.
|
||||
*
|
||||
* Return value: the copy of the current path. The caller owns the
|
||||
* returned object and should call cairo_path_destroy() when finished
|
||||
* with it.
|
||||
*
|
||||
* This function will always return a valid pointer, but the result
|
||||
* will have no data (<literal>data==NULL</literal> and
|
||||
* <literal>num_data==0</literal>), if either of the following
|
||||
|
|
|
@ -253,15 +253,16 @@ cairo_public void
|
|||
cairo_restore (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_set_target (cairo_t *cr, cairo_surface_t *target);
|
||||
moz_cairo_set_target (cairo_t *cr, cairo_surface_t *target);
|
||||
|
||||
/* XXX: I want to rethink this API
|
||||
cairo_public void
|
||||
cairo_push_group (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_public cairo_pattern_t *
|
||||
cairo_pop_group (cairo_t *cr);
|
||||
*/
|
||||
|
||||
cairo_public void
|
||||
cairo_pop_group_to_source (cairo_t *cr);
|
||||
|
||||
/* Modify state */
|
||||
|
||||
|
@ -1292,10 +1293,24 @@ cairo_public void
|
|||
cairo_pattern_get_matrix (cairo_pattern_t *pattern,
|
||||
cairo_matrix_t *matrix);
|
||||
|
||||
/**
|
||||
* cairo_extend_t
|
||||
* @CAIRO_EXTEND_NONE: pixels outside of the source 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
|
||||
* @CAIRO_EXTEND_PAD: pixels outside of the pattern copy
|
||||
* the closest pixel from the source (since cairo 1.2)
|
||||
*
|
||||
* #cairo_extend_t is used to describe how the area outside
|
||||
* of a pattern will be drawn.
|
||||
*/
|
||||
typedef enum _cairo_extend {
|
||||
CAIRO_EXTEND_NONE,
|
||||
CAIRO_EXTEND_REPEAT,
|
||||
CAIRO_EXTEND_REFLECT
|
||||
CAIRO_EXTEND_REFLECT,
|
||||
CAIRO_EXTEND_PAD
|
||||
} cairo_extend_t;
|
||||
|
||||
cairo_public void
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
#include "cairo-debug.h"
|
||||
#include <pixman.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, INT_##name)
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, INT_##name)
|
||||
|
@ -130,6 +132,7 @@
|
|||
#define INLINE
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if HAVE_PTHREAD_H
|
||||
# include <pthread.h>
|
||||
# define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
|
||||
|
@ -138,12 +141,7 @@
|
|||
# define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name)
|
||||
#endif
|
||||
|
||||
/* Since we have no way currently to initialize the mutexes and
|
||||
* cairo is only used from the main thread, turn off the critical
|
||||
* sections.
|
||||
*/
|
||||
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE
|
||||
#if 0
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
/* the real initialization must take place in DllMain */
|
||||
|
@ -152,13 +150,19 @@
|
|||
# define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name)
|
||||
# define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
|
||||
#endif
|
||||
|
||||
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE
|
||||
cairo_private void _cairo_beos_lock(void*);
|
||||
cairo_private void _cairo_beos_unlock(void*);
|
||||
/* the real initialization takes place in a global constructor */
|
||||
# define CAIRO_MUTEX_DECLARE(name) extern void* name;
|
||||
# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern void* name;
|
||||
# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name)
|
||||
# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name)
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
|
||||
#ifndef CAIRO_MUTEX_DECLARE
|
||||
#if 0
|
||||
# error "No mutex declarations. Cairo will not work with multiple threads." \
|
||||
"(Remove this #error directive to acknowledge & accept this limitation)."
|
||||
#endif
|
||||
# define CAIRO_MUTEX_DECLARE(name)
|
||||
# define CAIRO_MUTEX_DECLARE_GLOBAL(name)
|
||||
# define CAIRO_MUTEX_LOCK(name)
|
||||
|
@ -185,10 +189,6 @@ do { \
|
|||
assert (NOT_REACHED); \
|
||||
} while (0)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include "cairo-wideint.h"
|
||||
|
||||
typedef int32_t cairo_fixed_16_16_t;
|
||||
|
@ -261,7 +261,11 @@ typedef enum cairo_direction {
|
|||
} cairo_direction_t;
|
||||
|
||||
typedef struct _cairo_path_fixed cairo_path_fixed_t;
|
||||
typedef enum _cairo_clip_mode cairo_clip_mode_t;
|
||||
typedef enum _cairo_clip_mode {
|
||||
CAIRO_CLIP_MODE_PATH,
|
||||
CAIRO_CLIP_MODE_REGION,
|
||||
CAIRO_CLIP_MODE_MASK
|
||||
} cairo_clip_mode_t;
|
||||
typedef struct _cairo_clip_path cairo_clip_path_t;
|
||||
typedef struct _cairo_clip cairo_clip_t;
|
||||
|
||||
|
@ -329,12 +333,18 @@ struct _cairo_array {
|
|||
int size;
|
||||
int num_elements;
|
||||
int element_size;
|
||||
char *elements;
|
||||
char **elements;
|
||||
|
||||
cairo_bool_t is_snapshot;
|
||||
};
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_init (cairo_array_t *array, int element_size);
|
||||
|
||||
void
|
||||
_cairo_array_init_snapshot (cairo_array_t *array,
|
||||
const cairo_array_t *other);
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_fini (cairo_array_t *array);
|
||||
|
||||
|
@ -344,9 +354,18 @@ _cairo_array_grow_by (cairo_array_t *array, int additional);
|
|||
cairo_private void
|
||||
_cairo_array_truncate (cairo_array_t *array, int length);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_array_append (cairo_array_t *array,
|
||||
const void *elements, int num_elements);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_array_append (cairo_array_t *array, const void *element);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_array_append_multiple (cairo_array_t *array,
|
||||
const void *elements,
|
||||
int num_elements);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_array_allocate (cairo_array_t *array,
|
||||
int num_elements,
|
||||
void **elements);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_array_index (cairo_array_t *array, int index);
|
||||
|
@ -520,7 +539,7 @@ struct _cairo_scaled_font_backend {
|
|||
uint32_t ucs4);
|
||||
cairo_int_status_t
|
||||
(*show_glyphs) (void *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
|
@ -568,6 +587,16 @@ extern const cairo_private struct _cairo_scaled_font_backend cairo_atsui_scaled_
|
|||
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_stroke_style {
|
||||
double line_width;
|
||||
cairo_line_cap_t line_cap;
|
||||
cairo_line_join_t line_join;
|
||||
double miter_limit;
|
||||
double *dash;
|
||||
int num_dashes;
|
||||
double dash_offset;
|
||||
} cairo_stroke_style_t;
|
||||
|
||||
struct _cairo_surface_backend {
|
||||
cairo_surface_t *
|
||||
(*create_similar) (void *surface,
|
||||
|
@ -609,7 +638,7 @@ struct _cairo_surface_backend {
|
|||
|
||||
/* XXX: dst should be the first argument for consistency */
|
||||
cairo_int_status_t
|
||||
(*composite) (cairo_operator_t operator,
|
||||
(*composite) (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
|
@ -624,14 +653,14 @@ struct _cairo_surface_backend {
|
|||
|
||||
cairo_int_status_t
|
||||
(*fill_rectangles) (void *surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
|
||||
/* XXX: dst should be the first argument for consistency */
|
||||
cairo_int_status_t
|
||||
(*composite_trapezoids) (cairo_operator_t operator,
|
||||
(*composite_trapezoids) (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -708,8 +737,8 @@ struct _cairo_surface_backend {
|
|||
* surfaces as glyphs.
|
||||
*/
|
||||
cairo_int_status_t
|
||||
(*show_glyphs) (cairo_scaled_font_t *font,
|
||||
cairo_operator_t operator,
|
||||
(*old_show_glyphs) (cairo_scaled_font_t *font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *surface,
|
||||
int source_x,
|
||||
|
@ -721,14 +750,6 @@ struct _cairo_surface_backend {
|
|||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
cairo_int_status_t
|
||||
(*fill_path) (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
void *dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance);
|
||||
|
||||
void
|
||||
(*get_font_options) (void *surface,
|
||||
cairo_font_options_t *options);
|
||||
|
@ -749,6 +770,51 @@ struct _cairo_surface_backend {
|
|||
void
|
||||
(*scaled_glyph_fini) (cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
/* OK, I'm starting over somewhat by defining the 5 top-level
|
||||
* drawing operators for the surface backend here with consistent
|
||||
* naming and argument-order convensions. */
|
||||
cairo_int_status_t
|
||||
(*paint) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source);
|
||||
|
||||
cairo_int_status_t
|
||||
(*mask) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask);
|
||||
|
||||
cairo_int_status_t
|
||||
(*stroke) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_int_status_t
|
||||
(*fill) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_int_status_t
|
||||
(*show_glyphs) (void *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_surface_t *
|
||||
(*snapshot) (void *surface);
|
||||
};
|
||||
|
||||
typedef struct _cairo_format_masks {
|
||||
|
@ -772,10 +838,12 @@ struct _cairo_surface {
|
|||
double device_x_scale;
|
||||
double device_y_scale;
|
||||
|
||||
cairo_clip_t *clip;
|
||||
|
||||
/*
|
||||
* Each time a clip region is modified, it gets the next value in this
|
||||
* sequence. This means that clip regions for this surface are uniquely
|
||||
* identified andupdates to the clip can be readily identified
|
||||
* identified and updates to the clip can be readily identified
|
||||
*/
|
||||
unsigned int next_clip_serial;
|
||||
/*
|
||||
|
@ -787,6 +855,9 @@ struct _cairo_surface {
|
|||
* The special value '0' is reserved for the unclipped case.
|
||||
*/
|
||||
unsigned int current_clip_serial;
|
||||
|
||||
/* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */
|
||||
cairo_bool_t is_snapshot;
|
||||
};
|
||||
|
||||
struct _cairo_image_surface {
|
||||
|
@ -833,7 +904,8 @@ typedef enum {
|
|||
CAIRO_STOCK_TRANSPARENT
|
||||
} cairo_stock_t;
|
||||
|
||||
#define CAIRO_EXTEND_DEFAULT CAIRO_EXTEND_NONE
|
||||
#define CAIRO_EXTEND_SURFACE_DEFAULT CAIRO_EXTEND_NONE
|
||||
#define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD
|
||||
#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST
|
||||
|
||||
typedef enum {
|
||||
|
@ -843,11 +915,6 @@ typedef enum {
|
|||
CAIRO_PATTERN_RADIAL
|
||||
} cairo_pattern_type_t;
|
||||
|
||||
typedef struct _cairo_color_stop {
|
||||
cairo_fixed_t offset;
|
||||
cairo_color_t color;
|
||||
} cairo_color_stop_t;
|
||||
|
||||
struct _cairo_pattern {
|
||||
cairo_pattern_type_t type;
|
||||
unsigned int ref_count;
|
||||
|
@ -873,24 +940,20 @@ typedef struct _cairo_surface_pattern {
|
|||
typedef struct _cairo_gradient_pattern {
|
||||
cairo_pattern_t base;
|
||||
|
||||
cairo_color_stop_t *stops;
|
||||
int n_stops;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int n_stops;
|
||||
} cairo_gradient_pattern_t;
|
||||
|
||||
typedef struct _cairo_linear_pattern {
|
||||
cairo_gradient_pattern_t base;
|
||||
|
||||
cairo_point_double_t point0;
|
||||
cairo_point_double_t point1;
|
||||
|
||||
pixman_linear_gradient_t gradient;
|
||||
} cairo_linear_pattern_t;
|
||||
|
||||
typedef struct _cairo_radial_pattern {
|
||||
cairo_gradient_pattern_t base;
|
||||
|
||||
cairo_point_double_t center0;
|
||||
cairo_point_double_t center1;
|
||||
double radius0;
|
||||
double radius1;
|
||||
|
||||
pixman_radial_gradient_t gradient;
|
||||
} cairo_radial_pattern_t;
|
||||
|
||||
typedef union {
|
||||
|
@ -1008,17 +1071,26 @@ cairo_private cairo_gstate_t *
|
|||
_cairo_gstate_clone (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target);
|
||||
_moz_cairo_gstate_set_target (cairo_gstate_t *gstate, cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_begin_group (cairo_gstate_t *gstate);
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_end_group (cairo_gstate_t *gstate);
|
||||
cairo_private void
|
||||
_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_gstate_get_target (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_gstate_get_parent_target (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_gstate_get_original_target (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_clip_t *
|
||||
_cairo_gstate_get_clip (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source);
|
||||
|
||||
|
@ -1026,7 +1098,7 @@ cairo_private cairo_pattern_t *
|
|||
_cairo_gstate_get_source (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t operator);
|
||||
_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t op);
|
||||
|
||||
cairo_private cairo_operator_t
|
||||
_cairo_gstate_get_operator (cairo_gstate_t *gstate);
|
||||
|
@ -1234,7 +1306,10 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_operator_bounded (cairo_operator_t operator);
|
||||
_cairo_operator_bounded_by_mask (cairo_operator_t op);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_operator_bounded_by_source (cairo_operator_t op);
|
||||
|
||||
/* cairo_color.c */
|
||||
cairo_private const cairo_color_t *
|
||||
|
@ -1306,6 +1381,10 @@ _cairo_unscaled_font_destroy (cairo_unscaled_font_t *font);
|
|||
cairo_private void
|
||||
_cairo_font_options_init_default (cairo_font_options_t *options);
|
||||
|
||||
cairo_private void
|
||||
_cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other);
|
||||
|
||||
/* cairo_hull.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
|
||||
|
@ -1398,6 +1477,13 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
|
|||
double *x1, double *y1,
|
||||
double *x2, double *y2);
|
||||
|
||||
cairo_private void
|
||||
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley);
|
||||
|
||||
/* cairo_path_fill.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
||||
|
@ -1407,9 +1493,12 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
|||
|
||||
/* cairo_path_stroke.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps);
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_traps_t *traps);
|
||||
|
||||
/* cairo-scaled-font.c */
|
||||
|
||||
|
@ -1454,7 +1543,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
|
@ -1463,7 +1552,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
@ -1496,6 +1585,18 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
cairo_private void
|
||||
_cairo_scaled_font_map_destroy (void);
|
||||
|
||||
/* cairo-stroke-style.c */
|
||||
|
||||
cairo_private void
|
||||
_cairo_stroke_style_init (cairo_stroke_style_t *style);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
||||
cairo_stroke_style_t *other);
|
||||
|
||||
cairo_private void
|
||||
_cairo_stroke_style_fini (cairo_stroke_style_t *style);
|
||||
|
||||
/* cairo-surface.c */
|
||||
|
||||
extern const cairo_private cairo_surface_t _cairo_surface_nil;
|
||||
|
@ -1523,7 +1624,7 @@ cairo_private cairo_clip_mode_t
|
|||
_cairo_surface_get_clip_mode (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
_cairo_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
|
@ -1538,7 +1639,7 @@ _cairo_surface_composite (cairo_operator_t operator,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
int x,
|
||||
int y,
|
||||
|
@ -1547,27 +1648,58 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_surface_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_paint (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_mask (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_stroke (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_show_glyphs (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
_cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_antialias_t antialias,
|
||||
|
@ -1580,18 +1712,10 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator,
|
|||
cairo_trapezoid_t *traps,
|
||||
int ntraps);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src,
|
||||
cairo_operator_t operator,
|
||||
cairo_surface_t *dst,
|
||||
cairo_traps_t *traps,
|
||||
cairo_clip_t *clip,
|
||||
cairo_antialias_t antialias);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_surface_copy_page (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_surface_show_page (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
@ -1623,6 +1747,9 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
|||
cairo_surface_t *src,
|
||||
cairo_surface_t **clone_out);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_surface_snapshot (cairo_surface_t *surface);
|
||||
|
||||
cairo_private unsigned int
|
||||
_cairo_surface_get_current_clip_serial (cairo_surface_t *surface);
|
||||
|
||||
|
@ -1652,18 +1779,18 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
|
|||
cairo_rectangle_t *rectangle);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
_cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *surface,
|
||||
int source_x,
|
||||
int source_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
||||
|
@ -1715,6 +1842,10 @@ _cairo_format_from_content (cairo_content_t content);
|
|||
cairo_private cairo_content_t
|
||||
_cairo_content_from_format (cairo_format_t format);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
cairo_format_t format);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_image_surface_create_with_masks (unsigned char *data,
|
||||
cairo_format_masks_t *format,
|
||||
|
@ -1725,16 +1856,18 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
|
|||
cairo_private void
|
||||
_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
|
||||
pixman_region16_t *region);
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (cairo_surface_t *surface);
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||
|
||||
/* cairo_pen.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate);
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
double radius,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pen_init_empty (cairo_pen_t *pen);
|
||||
|
@ -1830,6 +1963,10 @@ _cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix,
|
|||
cairo_private double
|
||||
_cairo_matrix_transformed_circle_major_axis(cairo_matrix_t *matrix, double radius);
|
||||
|
||||
cairo_private void
|
||||
_cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
|
||||
pixman_transform_t *pixman_transform);
|
||||
|
||||
/* cairo_traps.c */
|
||||
cairo_private void
|
||||
_cairo_traps_init (cairo_traps_t *traps);
|
||||
|
@ -1865,6 +2002,13 @@ cairo_private cairo_status_t
|
|||
_cairo_traps_extract_region (cairo_traps_t *tr,
|
||||
pixman_region16_t **region);
|
||||
|
||||
cairo_private void
|
||||
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
|
||||
cairo_trapezoid_t *src_traps,
|
||||
int num_traps,
|
||||
double tx, double ty,
|
||||
double sx, double sy);
|
||||
|
||||
/* cairo_slope.c */
|
||||
cairo_private void
|
||||
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b);
|
||||
|
@ -1944,6 +2088,10 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
|||
cairo_surface_attributes_t *src_attributes,
|
||||
cairo_surface_attributes_t *mask_attributes);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
|
||||
cairo_antialias_t antialias);
|
||||
|
@ -2014,6 +2162,9 @@ _cairo_output_stream_create_for_file (const char *filename);
|
|||
cairo_private void
|
||||
_cairo_error (cairo_status_t status);
|
||||
|
||||
cairo_private int
|
||||
_cairo_dtostr (char *buffer, size_t size, double d);
|
||||
|
||||
/* Avoid unnecessary PLT entries. */
|
||||
|
||||
slim_hidden_proto(cairo_get_current_point)
|
||||
|
@ -2037,5 +2188,11 @@ slim_hidden_proto(cairo_restore)
|
|||
slim_hidden_proto(cairo_save)
|
||||
slim_hidden_proto(cairo_stroke_preserve)
|
||||
slim_hidden_proto(cairo_surface_destroy)
|
||||
slim_hidden_proto(cairo_push_group)
|
||||
slim_hidden_proto(cairo_pop_group)
|
||||
slim_hidden_proto(cairo_pop_group_to_source)
|
||||
slim_hidden_proto(moz_cairo_set_target)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
/* This isn't a "real" surface, but just something to be used by the
|
||||
* test suite to test a mythical backend that uses nothing but
|
||||
* fallbacks.
|
||||
*
|
||||
* The defining feature of this backend is that it has as many NULL
|
||||
* backend function entries as possible. The ones that aren't NULL are
|
||||
* simply those that must be implemented to have working fallbacks.
|
||||
* (Except for create_similar---fallbacks would work fine without
|
||||
* that---I implemented it here in order to create as many surfaces as
|
||||
* possible of type test_fallback_surface_t during the test suite
|
||||
* run).
|
||||
*
|
||||
* It's possible that this code might serve as a good starting point
|
||||
* for someone working on bringing up a new backend, starting with the
|
||||
* minimal all-fallbacks approach and working up gradually from
|
||||
* there.
|
||||
*/
|
||||
|
||||
#include "test-fallback-surface.h"
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _test_fallback_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* This is a cairo_image_surface to hold the actual contents. */
|
||||
cairo_surface_t *backing;
|
||||
} test_fallback_surface_t;
|
||||
|
||||
const cairo_private cairo_surface_backend_t test_fallback_surface_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_test_fallback_surface_create (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
test_fallback_surface_t *surface;
|
||||
cairo_surface_t *backing;
|
||||
|
||||
backing = cairo_image_surface_create (format, width, height);
|
||||
if (cairo_surface_status (backing))
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
surface = malloc (sizeof (test_fallback_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &test_fallback_surface_backend);
|
||||
|
||||
surface->backing = backing;
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_test_fallback_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
assert (CAIRO_CONTENT_VALID (content));
|
||||
|
||||
return _test_fallback_surface_create (_cairo_format_from_content (content),
|
||||
width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_fallback_surface_finish (void *abstract_surface)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_destroy (surface->backing);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_fallback_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_acquire_source_image (surface->backing,
|
||||
image_out, image_extra);
|
||||
}
|
||||
|
||||
static void
|
||||
_test_fallback_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
_cairo_surface_release_source_image (surface->backing,
|
||||
image, image_extra);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t**image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_acquire_dest_image (surface->backing,
|
||||
interest_rect,
|
||||
image_out,
|
||||
image_rect_out,
|
||||
image_extra);
|
||||
}
|
||||
|
||||
static void
|
||||
_test_fallback_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t*image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
_cairo_surface_release_dest_image (surface->backing,
|
||||
interest_rect,
|
||||
image,
|
||||
image_rect,
|
||||
image_extra);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_fallback_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->backing, rectangle);
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t test_fallback_surface_backend = {
|
||||
_test_fallback_surface_create_similar,
|
||||
_test_fallback_surface_finish,
|
||||
_test_fallback_surface_acquire_source_image,
|
||||
_test_fallback_surface_release_source_image,
|
||||
_test_fallback_surface_acquire_dest_image,
|
||||
_test_fallback_surface_release_dest_image,
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
NULL, /* intersect_clip_path */
|
||||
_test_fallback_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
NULL, /* paint */
|
||||
NULL, /* mask */
|
||||
NULL, /* stroke */
|
||||
NULL, /* fill */
|
||||
NULL, /* show_glyphs */
|
||||
NULL /* snapshot */
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef TEST_FALLBACK_SURFACE_H
|
||||
#define TEST_FALLBACK_SURFACE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
_test_fallback_surface_create (cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* TEST_FALLBACK_SURFACE_H */
|
|
@ -0,0 +1,325 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
/* This isn't a "real" surface, but just something to be used by the
|
||||
* test suite to help exercise the meta-surface paths in cairo.
|
||||
*
|
||||
* The defining feature of this backend is that it uses a meta surface
|
||||
* to record all operations, and then replays everything to an image
|
||||
* surface.
|
||||
*
|
||||
* It's possible that this code might serve as a good starting point
|
||||
* for someone working on bringing up a new meta-surface-based
|
||||
* backend.
|
||||
*/
|
||||
|
||||
#include "test-meta-surface.h"
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
typedef struct _test_meta_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* This is a cairo_meta_surface to record all operations. */
|
||||
cairo_surface_t *meta;
|
||||
|
||||
/* And this is a cairo_image_surface to hold the final result. */
|
||||
cairo_surface_t *image;
|
||||
|
||||
cairo_bool_t image_reflects_meta;
|
||||
} test_meta_surface_t;
|
||||
|
||||
const cairo_private cairo_surface_backend_t test_meta_surface_backend;
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_show_page (void *abstract_surface);
|
||||
|
||||
cairo_surface_t *
|
||||
_test_meta_surface_create (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
test_meta_surface_t *surface;
|
||||
|
||||
surface = malloc (sizeof (test_meta_surface_t));
|
||||
if (surface == NULL)
|
||||
goto FAIL;
|
||||
|
||||
_cairo_surface_init (&surface->base, &test_meta_surface_backend);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (width, height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
goto FAIL_CLEANUP_SURFACE;
|
||||
|
||||
surface->image = cairo_image_surface_create (format, width, height);
|
||||
if (cairo_surface_status (surface->image))
|
||||
goto FAIL_CLEANUP_META;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return &surface->base;
|
||||
|
||||
FAIL_CLEANUP_META:
|
||||
cairo_surface_destroy (surface->meta);
|
||||
FAIL_CLEANUP_SURFACE:
|
||||
free (surface);
|
||||
FAIL:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_meta_surface_finish (void *abstract_surface)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
cairo_surface_destroy (surface->image);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_meta_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
if (! surface->image_reflects_meta)
|
||||
_test_meta_surface_show_page (abstract_surface);
|
||||
|
||||
return _cairo_surface_acquire_source_image (surface->image,
|
||||
image_out, image_extra);
|
||||
}
|
||||
|
||||
static void
|
||||
_test_meta_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
_cairo_surface_release_source_image (surface->image,
|
||||
image, image_extra);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_show_page (void *abstract_surface)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->image_reflects_meta)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, surface->image);
|
||||
|
||||
surface->image_reflects_meta = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_intersect_clip_path (void *abstract_surface,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_intersect_clip_path (surface->meta,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_get_extents (surface->image, rectangle);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_paint (surface->meta, op, source);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_mask (surface->meta, op, source, mask);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_stroke (surface->meta, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_fill (surface->meta, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->image_reflects_meta = FALSE;
|
||||
|
||||
return _cairo_surface_show_glyphs (surface->meta, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_test_meta_surface_snapshot (void *abstract_other)
|
||||
{
|
||||
test_meta_surface_t *other = abstract_other;
|
||||
|
||||
/* XXX: Just making a snapshot of other->meta is what we really
|
||||
* want. But this currently triggers a bug somewhere (the "mask"
|
||||
* test from the test suite segfaults).
|
||||
*
|
||||
* For now, we'll create a new image surface and replay onto
|
||||
* that. It would be tempting to replay into other->image and then
|
||||
* return a snapshot of that, but that will cause the self-copy
|
||||
* test to fail, (since our replay will be affected by a clip that
|
||||
* should not have any effect on the use of the resulting snapshot
|
||||
* as a source).
|
||||
*/
|
||||
|
||||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
_cairo_surface_get_extents (other->image, &extents);
|
||||
|
||||
surface = cairo_surface_create_similar (other->image,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
_cairo_meta_surface_replay (other->meta, surface);
|
||||
|
||||
return surface;
|
||||
#endif
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t test_meta_surface_backend = {
|
||||
NULL, /* create_similar */
|
||||
_test_meta_surface_finish,
|
||||
_test_meta_surface_acquire_source_image,
|
||||
_test_meta_surface_release_source_image,
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
_test_meta_surface_show_page,
|
||||
NULL, /* set_clip_region */
|
||||
_test_meta_surface_intersect_clip_path,
|
||||
_test_meta_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
_test_meta_surface_paint,
|
||||
_test_meta_surface_mask,
|
||||
_test_meta_surface_stroke,
|
||||
_test_meta_surface_fill,
|
||||
_test_meta_surface_show_glyphs,
|
||||
_test_meta_surface_snapshot
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef TEST_META_SURFACE_H
|
||||
#define TEST_META_SURFACE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
_test_meta_surface_create (cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* TEST_META_SURFACE_H */
|
|
@ -0,0 +1,67 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
/* This isn't a "real" surface, but just something to be used by the
|
||||
* test suite to help exercise the paginated-surface paths in cairo.
|
||||
*
|
||||
* The defining feature of this backend is that it uses a paginated
|
||||
* surface to record all operations, and then replays everything to an
|
||||
* image surface.
|
||||
*
|
||||
* It's possible that this code might serve as a good starting point
|
||||
* for someone working on bringing up a new paginated-surface-based
|
||||
* backend.
|
||||
*/
|
||||
|
||||
#include "test-paginated-surface.h"
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
|
||||
cairo_surface_t *
|
||||
_test_paginated_surface_create_for_data (unsigned char *data,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
cairo_surface_t *target;
|
||||
|
||||
target = cairo_image_surface_create_for_data (data, format,
|
||||
width, height, stride);
|
||||
|
||||
return _cairo_paginated_surface_create (target, width, height);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef TEST_PAGINATED_SURFACE_H
|
||||
#define TEST_PAGINATED_SURFACE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
_test_paginated_surface_create_for_data (unsigned char *data,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int stride);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* TEST_PAGINATED_SURFACE_H */
|
|
@ -47,10 +47,14 @@ glitz_agl_fini (void);
|
|||
/* glitz_agl_format.c */
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_agl_find_drawable_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
glitz_agl_find_window_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_agl_find_pbuffer_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
|
||||
/* glitz_agl_drawable.c */
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ _glitz_agl_get_bundle (const char *name)
|
|||
{
|
||||
CFBundleRef bundle = 0;
|
||||
FSRefParam ref_param;
|
||||
unsigned char framework_name[256];
|
||||
char framework_name[256];
|
||||
|
||||
framework_name[0] = strlen (name);
|
||||
strcpy (&framework_name[1], name);
|
||||
|
@ -52,7 +52,7 @@ _glitz_agl_get_bundle (const char *name)
|
|||
|
||||
memset (&ref, 0, sizeof (ref));
|
||||
|
||||
ref_param.ioNamePtr = framework_name;
|
||||
ref_param.ioNamePtr = (unsigned char *) framework_name;
|
||||
ref_param.newRef = &ref;
|
||||
|
||||
if (PBMakeFSRefSync (&ref_param) == noErr) {
|
||||
|
@ -173,9 +173,9 @@ _glitz_agl_make_current (void *abstract_drawable,
|
|||
|
||||
if (drawable->base.width != drawable->width ||
|
||||
drawable->base.height != drawable->height)
|
||||
_glitz_agl_drawable_update_size (drawable,
|
||||
drawable->base.width,
|
||||
drawable->base.height);
|
||||
glitz_agl_drawable_update_size (drawable,
|
||||
drawable->base.width,
|
||||
drawable->base.height);
|
||||
|
||||
if (aglGetCurrentContext () != context->context)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ _glitz_agl_make_current (void *abstract_drawable,
|
|||
if (drawable->pbuffer)
|
||||
{
|
||||
AGLPbuffer pbuffer;
|
||||
GLuint unused;
|
||||
GLint unused;
|
||||
|
||||
aglGetPBuffer (context->context, &pbuffer,
|
||||
&unused, &unused, &unused);
|
||||
|
@ -242,7 +242,7 @@ _glitz_agl_context_get_proc_address (void *abstract_context,
|
|||
glitz_function_pointer_t func;
|
||||
CFBundleRef bundle;
|
||||
|
||||
_glitz_agl_make_current (drawable, context, NULL);
|
||||
_glitz_agl_make_current (drawable, context);
|
||||
|
||||
bundle = _glitz_agl_get_bundle ("OpenGL.framework");
|
||||
|
||||
|
@ -309,20 +309,23 @@ glitz_agl_context_get (glitz_agl_thread_info_t *thread_info,
|
|||
context->backend.make_current = _glitz_agl_make_current;
|
||||
context->backend.get_proc_address = _glitz_agl_context_get_proc_address;
|
||||
|
||||
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
|
||||
context->backend.read_buffer = _glitz_drawable_read_buffer;
|
||||
|
||||
context->backend.drawable_formats = NULL;
|
||||
context->backend.n_drawable_formats = 0;
|
||||
|
||||
if (screen_info->n_formats)
|
||||
if (thread_info->n_formats)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sizeof (glitz_int_drawable_format_t) * screen_info->n_formats;
|
||||
size = sizeof (glitz_int_drawable_format_t) * thread_info->n_formats;
|
||||
context->backend.drawable_formats = malloc (size);
|
||||
if (context->backend.drawable_formats)
|
||||
{
|
||||
memcpy (context->backend.drawable_formats, screen_info->formats,
|
||||
memcpy (context->backend.drawable_formats, thread_info->formats,
|
||||
size);
|
||||
context->backend.n_drawable_formats = screen_info->n_formats;
|
||||
context->backend.n_drawable_formats = thread_info->n_formats;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,9 +439,9 @@ _glitz_agl_context_update (glitz_agl_drawable_t *drawable,
|
|||
case GLITZ_DRAWABLE_CURRENT:
|
||||
if (drawable->base.width != drawable->width ||
|
||||
drawable->base.height != drawable->height)
|
||||
_glitz_agl_drawable_update_size (drawable,
|
||||
drawable->base.width,
|
||||
drawable->base.height);
|
||||
glitz_agl_drawable_update_size (drawable,
|
||||
drawable->base.width,
|
||||
drawable->base.height);
|
||||
|
||||
context = aglGetCurrentContext ();
|
||||
if (context != drawable->context->context) {
|
||||
|
@ -446,7 +449,7 @@ _glitz_agl_context_update (glitz_agl_drawable_t *drawable,
|
|||
} else {
|
||||
if (drawable->pbuffer) {
|
||||
AGLPbuffer pbuffer;
|
||||
GLuint unused;
|
||||
GLint unused;
|
||||
|
||||
aglGetPBuffer (drawable->context->context, &pbuffer,
|
||||
&unused, &unused, &unused);
|
||||
|
|
|
@ -52,7 +52,7 @@ _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info,
|
|||
drawable->height = height;
|
||||
|
||||
_glitz_drawable_init (&drawable->base,
|
||||
format,
|
||||
&thread_info->formats[format->id],
|
||||
&context->backend,
|
||||
width, height);
|
||||
|
||||
|
@ -73,16 +73,15 @@ _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info,
|
|||
}
|
||||
|
||||
glitz_bool_t
|
||||
_glitz_agl_drawable_update_size (glitz_agl_drawable_t *drawable,
|
||||
int width,
|
||||
int height)
|
||||
glitz_agl_drawable_update_size (glitz_agl_drawable_t *drawable,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (drawable->pbuffer)
|
||||
{
|
||||
glitz_agl_pbuffer_destroy (drawable->thread_info, drawable->pbuffer);
|
||||
glitz_agl_pbuffer_destroy (drawable->pbuffer);
|
||||
drawable->pbuffer =
|
||||
glitz_agl_pbuffer_create (drawable->thread_info,
|
||||
drawable->context->fbconfig,
|
||||
(int) width, (int) height);
|
||||
if (!drawable->pbuffer)
|
||||
return 0;
|
||||
|
@ -104,9 +103,6 @@ _glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info,
|
|||
glitz_agl_context_t *context;
|
||||
AGLPbuffer pbuffer;
|
||||
|
||||
if (!format->types.pbuffer)
|
||||
return NULL;
|
||||
|
||||
context = glitz_agl_context_get (thread_info, format);
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
@ -158,7 +154,7 @@ glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format,
|
|||
if (!thread_info)
|
||||
return NULL;
|
||||
|
||||
if (format->id >= screen_info->n_formats)
|
||||
if (format->id >= thread_info->n_formats)
|
||||
return NULL;
|
||||
|
||||
context = glitz_agl_context_get (thread_info, format);
|
||||
|
@ -186,7 +182,7 @@ glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format,
|
|||
if (!thread_info)
|
||||
return NULL;
|
||||
|
||||
if (format->id >= screen_info->n_formats)
|
||||
if (format->id >= thread_info->n_formats)
|
||||
return NULL;
|
||||
|
||||
return _glitz_agl_create_pbuffer_drawable (thread_info, format,
|
||||
|
@ -208,8 +204,9 @@ glitz_agl_destroy (void *abstract_drawable)
|
|||
*/
|
||||
glitz_agl_push_current (abstract_drawable, NULL,
|
||||
GLITZ_CONTEXT_CURRENT);
|
||||
glitz_program_map_fini (&drawable->base.backend->gl,
|
||||
glitz_program_map_fini (drawable->base.backend->gl,
|
||||
&drawable->thread_info->program_map);
|
||||
glitz_program_map_init (&drawable->thread_info->program_map);
|
||||
glitz_agl_pop_current (abstract_drawable);
|
||||
}
|
||||
|
||||
|
@ -219,7 +216,7 @@ glitz_agl_destroy (void *abstract_drawable)
|
|||
if (context == drawable->context->context) {
|
||||
if (drawable->pbuffer) {
|
||||
AGLPbuffer pbuffer;
|
||||
GLuint unused;
|
||||
GLint unused;
|
||||
|
||||
aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused);
|
||||
|
||||
|
|
|
@ -145,58 +145,60 @@ static int
|
|||
_glitz_agl_format_compare (const void *elem1,
|
||||
const void *elem2)
|
||||
{
|
||||
int i, score[2];
|
||||
glitz_drawable_format_t *format[2];
|
||||
glitz_int_drawable_format_t *format[2];
|
||||
int i, score[2];
|
||||
|
||||
format[0] = (glitz_drawable_format_t *) elem1;
|
||||
format[1] = (glitz_drawable_format_t *) elem2;
|
||||
format[0] = (glitz_int_drawable_format_t *) elem1;
|
||||
format[1] = (glitz_int_drawable_format_t *) elem2;
|
||||
i = score[0] = score[1] = 0;
|
||||
|
||||
for (; i < 2; i++) {
|
||||
if (format[i]->color.red_size) {
|
||||
if (format[i]->color.red_size == 8)
|
||||
for (; i < 2; i++)
|
||||
{
|
||||
if (format[i]->d.color.red_size)
|
||||
{
|
||||
if (format[i]->d.color.red_size >= 8)
|
||||
score[i] += 5;
|
||||
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->color.green_size) {
|
||||
if (format[i]->color.green_size == 8)
|
||||
if (format[i]->d.color.alpha_size)
|
||||
{
|
||||
if (format[i]->d.color.alpha_size >= 8)
|
||||
score[i] += 5;
|
||||
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->color.alpha_size) {
|
||||
if (format[i]->color.alpha_size == 8)
|
||||
score[i] += 5;
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->stencil_size)
|
||||
if (format[i]->d.stencil_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->depth_size)
|
||||
if (format[i]->d.depth_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->doublebuffer)
|
||||
if (format[i]->d.doublebuffer)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->types.window)
|
||||
if (format[i]->d.samples > 1)
|
||||
score[i] -= (20 - format[i]->d.samples);
|
||||
|
||||
if (format[i]->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->types.pbuffer)
|
||||
if (format[i]->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->samples > 1)
|
||||
score[i] -= (20 - format[i]->samples);
|
||||
if (format[i]->caveat)
|
||||
score[i] -= 1000;
|
||||
}
|
||||
|
||||
return score[1] - score[0];
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_add_format (glitz_agl_thread_info_t *thread_info,
|
||||
glitz_drawable_format_t *format,
|
||||
AGLPixelFormat pixel_format)
|
||||
_glitz_agl_add_format (glitz_agl_thread_info_t *thread_info,
|
||||
glitz_int_drawable_format_t *format,
|
||||
AGLPixelFormat pixel_format)
|
||||
{
|
||||
if (!glitz_drawable_format_find (thread_info->formats,
|
||||
thread_info->n_formats,
|
||||
|
@ -206,14 +208,14 @@ _glitz_add_format (glitz_agl_thread_info_t *thread_info,
|
|||
|
||||
thread_info->formats =
|
||||
realloc (thread_info->formats,
|
||||
sizeof (glitz_drawable_format_t) * (n + 1));
|
||||
sizeof (glitz_int_drawable_format_t) * (n + 1));
|
||||
thread_info->pixel_formats =
|
||||
realloc (thread_info->pixel_formats,
|
||||
sizeof (AGLPixelFormat) * (n + 1));
|
||||
|
||||
if (thread_info->formats && thread_info->pixel_formats) {
|
||||
thread_info->formats[n] = *format;
|
||||
thread_info->formats[n].id = n;
|
||||
thread_info->formats[n] = *(glitz_int_drawable_format_t*)format;
|
||||
thread_info->formats[n].d.id = n;
|
||||
thread_info->pixel_formats[n] = pixel_format;
|
||||
thread_info->n_formats++;
|
||||
}
|
||||
|
@ -223,12 +225,13 @@ _glitz_add_format (glitz_agl_thread_info_t *thread_info,
|
|||
void
|
||||
glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
|
||||
{
|
||||
glitz_drawable_format_t format;
|
||||
glitz_int_drawable_format_t format;
|
||||
AGLPixelFormat pixel_format, *new_pfs;
|
||||
int n_attribs_list, i;
|
||||
|
||||
format.types.window = 1;
|
||||
format.id = 0;
|
||||
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
format.d.id = 0;
|
||||
format.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
|
||||
n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *);
|
||||
|
||||
|
@ -245,20 +248,20 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
|
|||
}
|
||||
|
||||
aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value);
|
||||
format.doublebuffer = (value)? 1: 0;
|
||||
format.d.doublebuffer = (value)? 1: 0;
|
||||
|
||||
aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value);
|
||||
format.color.red_size = (unsigned short) value;
|
||||
format.d.color.red_size = (unsigned short) value;
|
||||
aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value);
|
||||
format.color.green_size = (unsigned short) value;
|
||||
format.d.color.green_size = (unsigned short) value;
|
||||
aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value);
|
||||
format.color.blue_size = (unsigned short) value;
|
||||
format.d.color.blue_size = (unsigned short) value;
|
||||
aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value);
|
||||
format.color.alpha_size = (unsigned short) value;
|
||||
format.d.color.alpha_size = (unsigned short) value;
|
||||
aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value);
|
||||
format.depth_size = (unsigned short) value;
|
||||
format.d.depth_size = (unsigned short) value;
|
||||
aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value);
|
||||
format.stencil_size = (unsigned short) value;
|
||||
format.d.stencil_size = (unsigned short) value;
|
||||
|
||||
if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK)
|
||||
{
|
||||
|
@ -266,42 +269,42 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
|
|||
&value);
|
||||
if (value) {
|
||||
aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value);
|
||||
format.samples = (unsigned short) (value > 1)? value: 1;
|
||||
format.d.samples = (unsigned short) (value > 1)? value: 1;
|
||||
} else
|
||||
format.samples = 1;
|
||||
format.d.samples = 1;
|
||||
} else
|
||||
format.samples = 1;
|
||||
format.d.samples = 1;
|
||||
|
||||
if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) {
|
||||
if (format.color.red_size && format.color.green_size &&
|
||||
format.color.blue_size && format.color.alpha_size &&
|
||||
format.doublebuffer == 0 && format.stencil_size == 0 &&
|
||||
format.depth_size == 0) {
|
||||
if (format.d.color.red_size && format.d.color.green_size &&
|
||||
format.d.color.blue_size && format.d.color.alpha_size &&
|
||||
format.d.doublebuffer == 0 && format.d.stencil_size == 0 &&
|
||||
format.d.depth_size == 0) {
|
||||
|
||||
if (thread_info->agl_feature_mask &
|
||||
GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK)
|
||||
format.types.pbuffer = 1;
|
||||
else if (format.samples == 1)
|
||||
format.types.pbuffer = 1;
|
||||
format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
else if (format.d.samples == 1)
|
||||
format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
else
|
||||
format.types.pbuffer = 0;
|
||||
format.types &= ~GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
} else
|
||||
format.types.pbuffer = 0;
|
||||
format.types &= ~GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
} else
|
||||
format.types.pbuffer = 0;
|
||||
format.types &= ~GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
|
||||
if (format.color.red_size ||
|
||||
format.color.green_size ||
|
||||
format.color.blue_size ||
|
||||
format.color.alpha_size)
|
||||
_glitz_add_format (thread_info, &format, pixel_format);
|
||||
if (format.d.color.red_size ||
|
||||
format.d.color.green_size ||
|
||||
format.d.color.blue_size ||
|
||||
format.d.color.alpha_size)
|
||||
_glitz_agl_add_format (thread_info, &format, pixel_format);
|
||||
}
|
||||
|
||||
if (!thread_info->n_formats)
|
||||
return;
|
||||
|
||||
qsort (thread_info->formats, thread_info->n_formats,
|
||||
sizeof (glitz_drawable_format_t), _glitz_agl_format_compare);
|
||||
sizeof (glitz_int_drawable_format_t), _glitz_agl_format_compare);
|
||||
|
||||
/*
|
||||
* Update AGLPixelFormat list so that it matches the sorted format list.
|
||||
|
@ -313,8 +316,8 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
|
|||
}
|
||||
|
||||
for (i = 0; i < thread_info->n_formats; i++) {
|
||||
new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].id];
|
||||
thread_info->formats[i].id = i;
|
||||
new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].d.id];
|
||||
thread_info->formats[i].d.id = i;
|
||||
}
|
||||
|
||||
free (thread_info->pixel_formats);
|
||||
|
@ -322,14 +325,43 @@ glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
|
|||
}
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_agl_find_drawable_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
glitz_agl_find_window_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
{
|
||||
glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get ();
|
||||
glitz_int_drawable_format_t itempl;
|
||||
glitz_agl_thread_info_t *thread_info =
|
||||
glitz_agl_thread_info_get ();
|
||||
|
||||
glitz_drawable_format_copy (templ, &itempl.d, mask);
|
||||
|
||||
itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
mask |= GLITZ_INT_FORMAT_WINDOW_MASK;
|
||||
|
||||
return glitz_drawable_format_find (thread_info->formats,
|
||||
thread_info->n_formats,
|
||||
mask, templ, count);
|
||||
mask, &itempl, count);
|
||||
}
|
||||
slim_hidden_def(glitz_agl_find_drawable_format);
|
||||
slim_hidden_def(glitz_agl_find_window_format);
|
||||
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_agl_find_pbuffer_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
{
|
||||
glitz_int_drawable_format_t itempl;
|
||||
glitz_agl_thread_info_t *thread_info =
|
||||
glitz_agl_thread_info_get ();
|
||||
|
||||
glitz_drawable_format_copy (templ, &itempl.d, mask);
|
||||
|
||||
itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
mask |= GLITZ_INT_FORMAT_PBUFFER_MASK;
|
||||
|
||||
return glitz_drawable_format_find (thread_info->formats,
|
||||
thread_info->n_formats,
|
||||
mask, &itempl, count);
|
||||
}
|
||||
slim_hidden_def(glitz_agl_find_pbuffer_format);
|
||||
|
||||
|
|
|
@ -130,6 +130,11 @@ glitz_agl_destroy (void *abstract_drawable);
|
|||
extern glitz_bool_t __internal_linkage
|
||||
glitz_agl_swap_buffers (void *abstract_drawable);
|
||||
|
||||
extern glitz_bool_t __internal_linkage
|
||||
glitz_agl_drawable_update_size (glitz_agl_drawable_t *drawable,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/* Avoid unnecessary PLT entries. */
|
||||
|
||||
slim_hidden_proto(glitz_agl_init)
|
||||
|
@ -137,5 +142,6 @@ slim_hidden_proto(glitz_agl_fini)
|
|||
slim_hidden_proto(glitz_agl_find_drawable_format)
|
||||
slim_hidden_proto(glitz_agl_create_drawable_for_window)
|
||||
slim_hidden_proto(glitz_agl_create_pbuffer_drawable)
|
||||
slim_hidden_proto(glitz_agl_drawable_update_size)
|
||||
|
||||
#endif /* GLITZ_GLXINT_H_INCLUDED */
|
||||
|
|
|
@ -45,6 +45,9 @@ _glitz_egl_format_compare (const void *elem1,
|
|||
|
||||
for (; i < 2; i++)
|
||||
{
|
||||
if (format[i]->d.color.fourcc != GLITZ_FOURCC_RGB)
|
||||
score[i] -= 1000;
|
||||
|
||||
if (format[i]->d.color.red_size)
|
||||
{
|
||||
if (format[i]->d.color.red_size >= 8)
|
||||
|
@ -118,7 +121,8 @@ _glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info)
|
|||
if (!egl_configs)
|
||||
return;
|
||||
|
||||
format.d.id = 0;
|
||||
format.d.id = 0;
|
||||
format.d.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
format.d.doublebuffer = 1;
|
||||
|
||||
eglGetConfigs (egl_display, egl_configs, num_configs, &num_configs);
|
||||
|
|
|
@ -122,7 +122,7 @@ _glitz_egl_make_current (void *abstract_drawable,
|
|||
drawable->base.height);
|
||||
|
||||
if ((eglGetCurrentContext () != context->egl_context) ||
|
||||
(eglGetCurrentSurface ( 0 ) != drawable->egl_surface))
|
||||
(eglGetCurrentSurface ( EGL_READ ) != drawable->egl_surface))
|
||||
{
|
||||
if (display_info->thread_info->cctx)
|
||||
{
|
||||
|
@ -206,6 +206,9 @@ glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
|
|||
context->backend.make_current = _glitz_egl_make_current;
|
||||
context->backend.get_proc_address = _glitz_egl_context_get_proc_address;
|
||||
|
||||
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
|
||||
context->backend.read_buffer = _glitz_drawable_read_buffer;
|
||||
|
||||
context->backend.drawable_formats = NULL;
|
||||
context->backend.n_drawable_formats = 0;
|
||||
|
||||
|
|
|
@ -215,6 +215,7 @@ glitz_egl_destroy (void *abstract_drawable)
|
|||
GLITZ_CONTEXT_CURRENT);
|
||||
glitz_program_map_fini (surface->base.backend->gl,
|
||||
&surface->screen_info->program_map);
|
||||
glitz_program_map_init (&surface->screen_info->program_map);
|
||||
glitz_egl_pop_current (abstract_drawable);
|
||||
}
|
||||
|
||||
|
|
|
@ -422,8 +422,10 @@ glitz_copy_area (glitz_surface_t *src,
|
|||
glitz_surface_pop_current (src);
|
||||
}
|
||||
|
||||
gl->read_buffer (src->buffer);
|
||||
gl->draw_buffer (dst->buffer);
|
||||
src->drawable->backend->read_buffer (src->drawable,
|
||||
src->buffer);
|
||||
dst->drawable->backend->draw_buffer (dst->drawable,
|
||||
dst->buffer);
|
||||
|
||||
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
|
||||
|
||||
|
@ -496,8 +498,8 @@ glitz_copy_area (glitz_surface_t *src,
|
|||
|
||||
gl->color_4us (0x0, 0x0, 0x0, 0xffff);
|
||||
|
||||
param.filter[0] = param.filter[1] = GLITZ_GL_CLAMP_TO_EDGE;
|
||||
param.wrap[0] = param.wrap[1] = GLITZ_GL_NEAREST;
|
||||
param.filter[0] = param.filter[1] = GLITZ_GL_NEAREST;
|
||||
param.wrap[0] = param.wrap[1] = GLITZ_GL_CLAMP_TO_EDGE;
|
||||
|
||||
glitz_texture_ensure_parameters (gl, texture, ¶m);
|
||||
|
||||
|
@ -596,7 +598,7 @@ glitz_copy_area (glitz_surface_t *src,
|
|||
{
|
||||
glitz_texture_t *texture;
|
||||
|
||||
gl->read_buffer (src->buffer);
|
||||
src->drawable->backend->read_buffer (src->drawable, src->buffer);
|
||||
|
||||
texture = glitz_surface_get_texture (dst, 1);
|
||||
if (texture)
|
||||
|
|
|
@ -26,19 +26,9 @@
|
|||
#ifndef GLITZ_H_INCLUDED
|
||||
#define GLITZ_H_INCLUDED
|
||||
|
||||
#if defined(__SVR4) && defined(__sun)
|
||||
# include <sys/int_types.h>
|
||||
#else
|
||||
# if defined(__OpenBSD__)
|
||||
# include <inttypes.h>
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define GLITZ_MAJOR 0
|
||||
#define GLITZ_MINOR 5
|
||||
#define GLITZ_REVISION 0
|
||||
#define GLITZ_REVISION 2
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
@ -158,17 +148,29 @@ typedef enum {
|
|||
|
||||
typedef unsigned long glitz_format_id_t;
|
||||
|
||||
typedef unsigned int glitz_fourcc_t;
|
||||
|
||||
#define GLITZ_FORMAT_FOURCC_MASK (1L << 5)
|
||||
|
||||
#define GLITZ_FOURCC(a, b, c, d) \
|
||||
((a) | (b) << 8 | (c) << 16 | ((glitz_fourcc_t) (d)) << 24)
|
||||
|
||||
#define GLITZ_FOURCC_RGB ((glitz_fourcc_t) 0x0)
|
||||
#define GLITZ_FOURCC_YV12 GLITZ_FOURCC ('Y', 'V', '1', '2')
|
||||
#define GLITZ_FOURCC_YUY2 GLITZ_FOURCC ('Y', 'U', 'Y', '2')
|
||||
|
||||
typedef struct _glitz_color_format_t {
|
||||
glitz_fourcc_t fourcc;
|
||||
unsigned short red_size;
|
||||
unsigned short green_size;
|
||||
unsigned short blue_size;
|
||||
unsigned short alpha_size;
|
||||
} glitz_color_format_t;
|
||||
|
||||
#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 5)
|
||||
#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 6)
|
||||
#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 7)
|
||||
#define GLITZ_FORMAT_SAMPLES_MASK (1L << 8)
|
||||
#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 6)
|
||||
#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 7)
|
||||
#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 8)
|
||||
#define GLITZ_FORMAT_SAMPLES_MASK (1L << 9)
|
||||
|
||||
typedef struct _glitz_drawable_format_t {
|
||||
glitz_format_id_t id;
|
||||
|
@ -179,15 +181,8 @@ typedef struct _glitz_drawable_format_t {
|
|||
glitz_bool_t doublebuffer;
|
||||
} glitz_drawable_format_t;
|
||||
|
||||
#define GLITZ_FORMAT_TYPE_MASK (1L << 5)
|
||||
|
||||
typedef enum {
|
||||
GLITZ_FORMAT_TYPE_COLOR
|
||||
} glitz_format_type_t;
|
||||
|
||||
typedef struct _glitz_format_t {
|
||||
glitz_format_id_t id;
|
||||
glitz_format_type_t type;
|
||||
glitz_color_format_t color;
|
||||
} glitz_format_t;
|
||||
|
||||
|
@ -482,6 +477,15 @@ void
|
|||
glitz_context_bind_texture (glitz_context_t *context,
|
||||
glitz_texture_object_t *texture);
|
||||
|
||||
void
|
||||
glitz_context_draw_buffers (glitz_context_t *context,
|
||||
const glitz_drawable_buffer_t *buffers,
|
||||
int n);
|
||||
|
||||
void
|
||||
glitz_context_read_buffer (glitz_context_t *context,
|
||||
const glitz_drawable_buffer_t buffer);
|
||||
|
||||
|
||||
/* glitz_rect.c */
|
||||
|
||||
|
@ -579,6 +583,7 @@ typedef struct _glitz_pixel_masks {
|
|||
} glitz_pixel_masks_t;
|
||||
|
||||
typedef struct _glitz_pixel_format {
|
||||
glitz_fourcc_t fourcc;
|
||||
glitz_pixel_masks_t masks;
|
||||
int xoffset;
|
||||
int skip_lines;
|
||||
|
|
|
@ -347,7 +347,7 @@ _glitz_combine_solid_solidc (glitz_composite_op_t *op)
|
|||
|
||||
if (op->solid->alpha > 0)
|
||||
op->gl->blend_color ((glitz_gl_clampf_t)
|
||||
op->solid->red / op->solid->alpha,
|
||||
op->solid->red / op->solid->alpha,
|
||||
(glitz_gl_clampf_t)
|
||||
op->solid->green / op->solid->alpha,
|
||||
(glitz_gl_clampf_t)
|
||||
|
@ -421,9 +421,10 @@ _glitz_combine_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = {
|
|||
((SURFACE_PAD (surface))? \
|
||||
(TEXTURE_PADABLE (&(surface)->texture)) \
|
||||
: \
|
||||
( \
|
||||
(!SURFACE_PROJECTIVE_TRANSFORM (surface)) || \
|
||||
((feature_mask) & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) \
|
||||
(TEXTURE_CLAMPABLE (&(surface)->texture) && \
|
||||
((!SURFACE_PROJECTIVE_TRANSFORM (surface)) || \
|
||||
((feature_mask) & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
|
|
@ -110,6 +110,11 @@ void
|
|||
glitz_context_make_current (glitz_context_t *context,
|
||||
glitz_drawable_t *drawable)
|
||||
{
|
||||
glitz_lose_current_function_t lose_current;
|
||||
|
||||
lose_current = context->lose_current;
|
||||
context->lose_current = 0;
|
||||
|
||||
if (drawable != context->drawable)
|
||||
{
|
||||
glitz_drawable_reference (drawable);
|
||||
|
@ -145,6 +150,8 @@ glitz_context_make_current (glitz_context_t *context,
|
|||
GLITZ_DAMAGE_SOLID_MASK);
|
||||
}
|
||||
|
||||
context->lose_current = lose_current;
|
||||
|
||||
drawable->backend->make_current (drawable, context);
|
||||
}
|
||||
slim_hidden_def(glitz_context_make_current);
|
||||
|
@ -179,3 +186,63 @@ glitz_context_bind_texture (glitz_context_t *context,
|
|||
&texture->param);
|
||||
}
|
||||
slim_hidden_def(glitz_context_bind_texture);
|
||||
|
||||
void
|
||||
glitz_context_draw_buffers (glitz_context_t *context,
|
||||
const glitz_drawable_buffer_t *buffers,
|
||||
int n)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
|
||||
#define FRONT_BIT (1 << 0)
|
||||
#define BACK_BIT (1 << 1)
|
||||
|
||||
while (n--)
|
||||
{
|
||||
switch (*buffers++) {
|
||||
case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR:
|
||||
mask |= FRONT_BIT;
|
||||
break;
|
||||
case GLITZ_DRAWABLE_BUFFER_BACK_COLOR:
|
||||
mask |= BACK_BIT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
if (mask == (FRONT_BIT | BACK_BIT))
|
||||
context->drawable->backend->draw_buffer (context->drawable,
|
||||
GLITZ_GL_FRONT_AND_BACK);
|
||||
else if (mask == FRONT_BIT)
|
||||
context->drawable->backend->draw_buffer (context->drawable,
|
||||
GLITZ_GL_FRONT);
|
||||
else
|
||||
context->drawable->backend->draw_buffer (context->drawable,
|
||||
GLITZ_GL_BACK);
|
||||
}
|
||||
|
||||
#undef FRONT_BIT
|
||||
#undef BACK_BIT
|
||||
|
||||
}
|
||||
slim_hidden_def(glitz_context_draw_buffers);
|
||||
|
||||
void
|
||||
glitz_context_read_buffer (glitz_context_t *context,
|
||||
const glitz_drawable_buffer_t buffer)
|
||||
{
|
||||
switch (buffer) {
|
||||
case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR:
|
||||
context->drawable->backend->read_buffer (context->drawable,
|
||||
GLITZ_GL_FRONT);
|
||||
break;
|
||||
case GLITZ_DRAWABLE_BUFFER_BACK_COLOR:
|
||||
context->drawable->backend->read_buffer (context->drawable,
|
||||
GLITZ_GL_BACK);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
slim_hidden_def(glitz_context_read_buffer);
|
||||
|
|
|
@ -55,6 +55,28 @@ _glitz_drawable_init (glitz_drawable_t *drawable,
|
|||
drawable->update_all = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_glitz_drawable_draw_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer)
|
||||
{
|
||||
glitz_drawable_t *drawable = abstract_drawable;
|
||||
|
||||
GLITZ_GL_DRAWABLE (drawable);
|
||||
|
||||
gl->draw_buffer (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
_glitz_drawable_read_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer)
|
||||
{
|
||||
glitz_drawable_t *drawable = abstract_drawable;
|
||||
|
||||
GLITZ_GL_DRAWABLE (drawable);
|
||||
|
||||
gl->read_buffer (buffer);
|
||||
}
|
||||
|
||||
static glitz_bool_t
|
||||
_glitz_drawable_size_check (glitz_drawable_t *other,
|
||||
unsigned int width,
|
||||
|
@ -241,8 +263,8 @@ glitz_drawable_swap_buffer_region (glitz_drawable_t *drawable,
|
|||
|
||||
gl->disable (GLITZ_GL_DITHER);
|
||||
|
||||
gl->read_buffer (GLITZ_GL_BACK);
|
||||
gl->draw_buffer (GLITZ_GL_FRONT);
|
||||
drawable->backend->read_buffer (drawable, GLITZ_GL_BACK);
|
||||
drawable->backend->draw_buffer (drawable, GLITZ_GL_FRONT);
|
||||
|
||||
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
|
||||
|
||||
|
|
|
@ -107,6 +107,10 @@ glitz_filter_set_params (glitz_surface_t *surface,
|
|||
|
||||
_glitz_filter_params_set (&dm, 3.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&dn, 3.0f, ¶ms, &n_params);
|
||||
|
||||
glitz_clamp_value (&dm, 1.0f, 1024.0f);
|
||||
glitz_clamp_value (&dn, 1.0f, 1024.0f);
|
||||
|
||||
m = dm;
|
||||
n = dn;
|
||||
|
||||
|
@ -130,8 +134,10 @@ glitz_filter_set_params (glitz_surface_t *surface,
|
|||
_glitz_filter_params_set (&weight, 0.0f, ¶ms, &n_params);
|
||||
if (weight != 0.0f) {
|
||||
vec = &vecs[surface->filter_params->id++];
|
||||
vec->v[0] = (i - cx) * surface->texture.texcoord_width_unit;
|
||||
vec->v[1] = (cy - j) * surface->texture.texcoord_height_unit;
|
||||
vec->v[0] = (i - cx) *
|
||||
surface->texture.texcoord_width_unit;
|
||||
vec->v[1] = (cy - j) *
|
||||
surface->texture.texcoord_height_unit;
|
||||
vec->v[2] = weight;
|
||||
vec->v[3] = 0.0f;
|
||||
}
|
||||
|
@ -211,15 +217,16 @@ glitz_filter_set_params (glitz_surface_t *surface,
|
|||
if (size < 2)
|
||||
size = 2;
|
||||
|
||||
if (_glitz_filter_params_ensure (surface, size + 1))
|
||||
return GLITZ_STATUS_NO_MEMORY;
|
||||
|
||||
vecs = surface->filter_params->vectors;
|
||||
|
||||
if (filter == GLITZ_FILTER_LINEAR_GRADIENT) {
|
||||
glitz_float_t length, angle, dh, dv;
|
||||
if (filter == GLITZ_FILTER_LINEAR_GRADIENT)
|
||||
{
|
||||
glitz_float_t length, dh, dv;
|
||||
glitz_float_t start_x, start_y, stop_x, stop_y;
|
||||
|
||||
if (_glitz_filter_params_ensure (surface, size + 1))
|
||||
return GLITZ_STATUS_NO_MEMORY;
|
||||
|
||||
vecs = surface->filter_params->vectors;
|
||||
|
||||
_glitz_filter_params_set (&start_x, 0.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&start_y, 0.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&stop_x, 1.0f, ¶ms, &n_params);
|
||||
|
@ -228,32 +235,48 @@ glitz_filter_set_params (glitz_surface_t *surface,
|
|||
dh = stop_x - start_x;
|
||||
dv = stop_y - start_y;
|
||||
|
||||
length = sqrtf (dh * dh + dv * dv);
|
||||
length = dh * dh + dv * dv;
|
||||
|
||||
angle = -atan2f (dv, dh);
|
||||
vecs->v[0] = dh / length;
|
||||
vecs->v[1] = dv / length;
|
||||
vecs->v[2] = -vecs->v[0] * start_x - vecs->v[1] * start_y;
|
||||
vecs->v[3] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
glitz_float_t r0, r1, r, x0, y0, x1, y1, dx, dy;
|
||||
|
||||
vecs->v[2] = cosf (angle);
|
||||
vecs->v[3] = -sinf (angle);
|
||||
if (_glitz_filter_params_ensure (surface, size + 2))
|
||||
return GLITZ_STATUS_NO_MEMORY;
|
||||
|
||||
vecs->v[0] = vecs->v[2] * start_x;
|
||||
vecs->v[0] += vecs->v[3] * start_y;
|
||||
vecs = surface->filter_params->vectors;
|
||||
|
||||
vecs->v[1] = (length)? 1.0f / length: 2147483647.0f;
|
||||
} else {
|
||||
glitz_float_t r0, r1;
|
||||
|
||||
_glitz_filter_params_set (&vecs->v[0], 0.5f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&vecs->v[1], 0.5f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&x0, 0.5f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&y0, 0.5f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&r0, 0.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&r1, 0.5f, ¶ms, &n_params);
|
||||
|
||||
_glitz_filter_params_set (&x1, x0, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&y1, y0, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&r1, r0 + 0.5f, ¶ms, &n_params);
|
||||
|
||||
glitz_clamp_value (&r0, 0.0f, r1);
|
||||
|
||||
vecs->v[2] = r0;
|
||||
if (r1 != r0)
|
||||
vecs->v[3] = 1.0f / (r1 - r0);
|
||||
else
|
||||
vecs->v[3] = 2147483647.0f;
|
||||
r = r0 / r1;
|
||||
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
|
||||
vecs->v[0] = x0 - r * dx;
|
||||
vecs->v[1] = y0 - r * dy;
|
||||
vecs->v[2] = dx * 2.0f;
|
||||
vecs->v[3] = dy * 2.0f;
|
||||
|
||||
vecs++;
|
||||
|
||||
vecs->v[0] = 1.0f / (1.0f + r);
|
||||
vecs->v[1] = -r * vecs->v[0];
|
||||
vecs->v[2] = (r1 * r1 - dx * dx - dy * dy) * 4.0f;
|
||||
vecs->v[3] = 2.0f / vecs->v[2];
|
||||
}
|
||||
|
||||
vecs++;
|
||||
|
@ -309,10 +332,35 @@ glitz_filter_set_params (glitz_surface_t *surface,
|
|||
break;
|
||||
case GLITZ_FILTER_BILINEAR:
|
||||
case GLITZ_FILTER_NEAREST:
|
||||
if (surface->filter_params)
|
||||
free (surface->filter_params);
|
||||
switch (surface->format->color.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
if (_glitz_filter_params_ensure (surface, 2))
|
||||
return GLITZ_STATUS_NO_MEMORY;
|
||||
|
||||
surface->filter_params = NULL;
|
||||
vecs = surface->filter_params->vectors;
|
||||
|
||||
vecs->v[0] = 0.0f;
|
||||
vecs->v[1] = surface->texture.texcoord_height_unit *
|
||||
((surface->texture.box.y2 + 1) & ~1);
|
||||
vecs->v[2] = surface->texture.texcoord_width_unit *
|
||||
(surface->texture.width >> 1);
|
||||
vecs->v[3] = 0.0f;
|
||||
|
||||
vecs++;
|
||||
|
||||
vecs->v[0] = surface->texture.texcoord_width_unit;
|
||||
vecs->v[1] = surface->texture.texcoord_height_unit;
|
||||
vecs->v[2] = surface->texture.texcoord_width_unit *
|
||||
surface->texture.box.x2 - vecs->v[0];
|
||||
vecs->v[3] = surface->texture.texcoord_height_unit *
|
||||
surface->texture.box.y2 - vecs->v[1];
|
||||
|
||||
surface->filter_params->id = 1;
|
||||
break;
|
||||
default:
|
||||
free (surface->filter_params);
|
||||
surface->filter_params = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -325,6 +373,9 @@ glitz_gl_uint_t
|
|||
glitz_filter_get_fragment_program (glitz_surface_t *surface,
|
||||
glitz_composite_op_t *op)
|
||||
{
|
||||
if (surface->filter_params->fp_type == GLITZ_FP_UNSUPPORTED)
|
||||
return 0;
|
||||
|
||||
return glitz_get_fragment_program (op,
|
||||
surface->filter_params->fp_type,
|
||||
surface->filter_params->id);
|
||||
|
@ -334,43 +385,56 @@ void
|
|||
glitz_filter_set_type (glitz_surface_t *surface,
|
||||
glitz_filter_t filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case GLITZ_FILTER_CONVOLUTION:
|
||||
case GLITZ_FILTER_GAUSSIAN:
|
||||
surface->filter_params->fp_type = GLITZ_FP_CONVOLUTION;
|
||||
switch (surface->format->color.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
switch (filter) {
|
||||
case GLITZ_FILTER_BILINEAR:
|
||||
case GLITZ_FILTER_NEAREST:
|
||||
surface->filter_params->fp_type = GLITZ_FP_COLORSPACE_YV12;
|
||||
break;
|
||||
default:
|
||||
surface->filter_params->fp_type = GLITZ_FP_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GLITZ_FILTER_LINEAR_GRADIENT:
|
||||
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
|
||||
if (SURFACE_MIRRORED (surface))
|
||||
default:
|
||||
switch (filter) {
|
||||
case GLITZ_FILTER_CONVOLUTION:
|
||||
case GLITZ_FILTER_GAUSSIAN:
|
||||
surface->filter_params->fp_type = GLITZ_FP_CONVOLUTION;
|
||||
break;
|
||||
case GLITZ_FILTER_LINEAR_GRADIENT:
|
||||
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
|
||||
if (SURFACE_MIRRORED (surface))
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_REFLECT;
|
||||
else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_REPEAT;
|
||||
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_REFLECT;
|
||||
else
|
||||
GLITZ_FP_LINEAR_GRADIENT_NEAREST;
|
||||
} else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_REPEAT;
|
||||
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_NEAREST;
|
||||
} else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT;
|
||||
break;
|
||||
case GLITZ_FILTER_RADIAL_GRADIENT:
|
||||
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
|
||||
if (SURFACE_MIRRORED (surface))
|
||||
GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT;
|
||||
break;
|
||||
case GLITZ_FILTER_RADIAL_GRADIENT:
|
||||
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
|
||||
if (SURFACE_MIRRORED (surface))
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_RADIAL_GRADIENT_REFLECT;
|
||||
else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_RADIAL_GRADIENT_REPEAT;
|
||||
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_RADIAL_GRADIENT_REFLECT;
|
||||
else
|
||||
GLITZ_FP_RADIAL_GRADIENT_NEAREST;
|
||||
} else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_RADIAL_GRADIENT_REPEAT;
|
||||
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
|
||||
surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_NEAREST;
|
||||
} else
|
||||
surface->filter_params->fp_type =
|
||||
GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT;
|
||||
break;
|
||||
case GLITZ_FILTER_BILINEAR:
|
||||
case GLITZ_FILTER_NEAREST:
|
||||
break;
|
||||
GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,6 +466,15 @@ glitz_filter_enable (glitz_surface_t *surface,
|
|||
|
||||
vec++;
|
||||
|
||||
j = 1;
|
||||
if (surface->filter == GLITZ_FILTER_RADIAL_GRADIENT)
|
||||
{
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, j++,
|
||||
vec->v);
|
||||
|
||||
vec++;
|
||||
}
|
||||
|
||||
if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT ||
|
||||
fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) {
|
||||
glitz_vec4_t v;
|
||||
|
@ -410,10 +483,8 @@ glitz_filter_enable (glitz_surface_t *surface,
|
|||
v.v[2] = 0.0f;
|
||||
v.v[3] = (vec->v[3])? 1.0f / vec->v[3]: 1.0f;
|
||||
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 1, v.v);
|
||||
j = 2;
|
||||
} else
|
||||
j = 1;
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, j++, v.v);
|
||||
}
|
||||
|
||||
for (i = 0; i < surface->filter_params->id; i++, vec++)
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM,
|
||||
|
@ -432,6 +503,18 @@ glitz_filter_enable (glitz_surface_t *surface,
|
|||
} break;
|
||||
case GLITZ_FILTER_BILINEAR:
|
||||
case GLITZ_FILTER_NEAREST:
|
||||
switch (surface->format->color.fourcc) {
|
||||
case GLITZ_FOURCC_YV12: {
|
||||
glitz_vec4_t *vec;
|
||||
|
||||
vec = surface->filter_params->vectors;
|
||||
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 0,
|
||||
vec[0].v);
|
||||
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 1,
|
||||
vec[1].v);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,28 +31,32 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct _texture_format {
|
||||
static struct _texture_format {
|
||||
glitz_gl_int_t texture_format;
|
||||
glitz_format_t format;
|
||||
} _texture_formats[] = {
|
||||
{ GLITZ_GL_ALPHA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 4 } } },
|
||||
{ GLITZ_GL_ALPHA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 8 } } },
|
||||
{ GLITZ_GL_ALPHA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 12 } } },
|
||||
{ GLITZ_GL_ALPHA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 16 } } },
|
||||
{ GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 3, 3, 2, 0 } } },
|
||||
{ GLITZ_GL_RGB4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 0 } } },
|
||||
{ GLITZ_GL_RGB5, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 6, 5, 0 } } },
|
||||
{ GLITZ_GL_RGB8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 0 } } },
|
||||
{ GLITZ_GL_RGB10, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 0 } } },
|
||||
{ GLITZ_GL_RGB12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 0 } } },
|
||||
{ GLITZ_GL_RGB16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 0 } } },
|
||||
{ GLITZ_GL_RGBA2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 2, 2, 2, 2 } } },
|
||||
{ GLITZ_GL_RGB5_A1, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 5, 5, 1 } } },
|
||||
{ GLITZ_GL_RGBA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 4 } } },
|
||||
{ GLITZ_GL_RGBA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 8 } } },
|
||||
{ GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 2 } } },
|
||||
{ GLITZ_GL_RGBA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } },
|
||||
{ GLITZ_GL_RGBA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } }
|
||||
{ GLITZ_GL_ALPHA4, { 0, { GLITZ_FOURCC_RGB, 0, 0, 0, 4 } } },
|
||||
{ GLITZ_GL_ALPHA8, { 0, { GLITZ_FOURCC_RGB, 0, 0, 0, 8 } } },
|
||||
{ GLITZ_GL_ALPHA12, { 0, { GLITZ_FOURCC_RGB, 0, 0, 0, 12 } } },
|
||||
{ GLITZ_GL_ALPHA16, { 0, { GLITZ_FOURCC_RGB, 0, 0, 0, 16 } } },
|
||||
{ GLITZ_GL_R3_G3_B2, { 0, { GLITZ_FOURCC_RGB, 3, 3, 2, 0 } } },
|
||||
{ GLITZ_GL_RGB4, { 0, { GLITZ_FOURCC_RGB, 4, 4, 4, 0 } } },
|
||||
{ GLITZ_GL_RGB5, { 0, { GLITZ_FOURCC_RGB, 5, 6, 5, 0 } } },
|
||||
{ GLITZ_GL_RGB8, { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 } } },
|
||||
{ GLITZ_GL_RGB10, { 0, { GLITZ_FOURCC_RGB, 10, 10, 10, 0 } } },
|
||||
{ GLITZ_GL_RGB12, { 0, { GLITZ_FOURCC_RGB, 12, 12, 12, 0 } } },
|
||||
{ GLITZ_GL_RGB16, { 0, { GLITZ_FOURCC_RGB, 16, 16, 16, 0 } } },
|
||||
{ GLITZ_GL_RGBA2, { 0, { GLITZ_FOURCC_RGB, 2, 2, 2, 2 } } },
|
||||
{ GLITZ_GL_RGB5_A1, { 0, { GLITZ_FOURCC_RGB, 5, 5, 5, 1 } } },
|
||||
{ GLITZ_GL_RGBA4, { 0, { GLITZ_FOURCC_RGB, 4, 4, 4, 4 } } },
|
||||
{ GLITZ_GL_RGBA8, { 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 } } },
|
||||
{ GLITZ_GL_RGB10_A2, { 0, { GLITZ_FOURCC_RGB, 10, 10, 10, 2 } } },
|
||||
{ GLITZ_GL_RGBA12, { 0, { GLITZ_FOURCC_RGB, 12, 12, 12, 12 } } },
|
||||
{ GLITZ_GL_RGBA16, { 0, { GLITZ_FOURCC_RGB, 16, 16, 16, 16 } } }
|
||||
};
|
||||
|
||||
static glitz_format_t _texture_format_yv12 = {
|
||||
0, { GLITZ_FOURCC_YV12, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -79,7 +83,8 @@ void
|
|||
glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
|
||||
glitz_format_t **formats,
|
||||
glitz_gl_int_t **texture_formats,
|
||||
int *n_formats)
|
||||
int *n_formats,
|
||||
unsigned long features)
|
||||
{
|
||||
glitz_gl_int_t value;
|
||||
int i, n_texture_formats;
|
||||
|
@ -88,12 +93,12 @@ glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
|
|||
sizeof (_texture_formats) / sizeof (struct _texture_format);
|
||||
|
||||
for (i = 0; i < n_texture_formats; i++) {
|
||||
gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0,
|
||||
_texture_formats[i].texture_format, 1, 1, 0,
|
||||
GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
|
||||
switch (_texture_formats[i].format.color.fourcc) {
|
||||
case GLITZ_FOURCC_RGB:
|
||||
gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0,
|
||||
_texture_formats[i].texture_format, 1, 1, 0,
|
||||
GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
switch (_texture_formats[i].format.type) {
|
||||
case GLITZ_FORMAT_TYPE_COLOR:
|
||||
if (_texture_formats[i].format.color.red_size) {
|
||||
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
|
||||
GLITZ_GL_TEXTURE_RED_SIZE,
|
||||
|
@ -136,6 +141,13 @@ glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
|
|||
_texture_formats[i].texture_format,
|
||||
&_texture_formats[i].format);
|
||||
}
|
||||
|
||||
/* formats used for YUV surfaces */
|
||||
if (features & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)
|
||||
{
|
||||
_glitz_add_texture_format (formats, texture_formats, n_formats,
|
||||
GLITZ_GL_LUMINANCE8, &_texture_format_yv12);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -155,7 +167,7 @@ _glitz_add_drawable_format (glitz_int_drawable_format_t *format,
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Available drawable formats needs to be validated is a similar way
|
||||
/* TODO: Available drawable formats needs to be validated in a similar way
|
||||
as surface formats. */
|
||||
void
|
||||
_glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl,
|
||||
|
@ -167,10 +179,10 @@ _glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl,
|
|||
{
|
||||
glitz_int_drawable_format_t format;
|
||||
glitz_drawable_format_t d[] = {
|
||||
{ 0, { 8, 8, 8, 0 }, 0, 0, 1, 0 },
|
||||
{ 0, { 8, 8, 8, 8 }, 0, 0, 1, 0 },
|
||||
{ 0, { 8, 8, 8, 0 }, 24, 8, 1, 1 },
|
||||
{ 0, { 8, 8, 8, 8 }, 24, 8, 1, 1 }
|
||||
{ 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 0, 0, 1, 0 },
|
||||
{ 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 0, 0, 1, 0 },
|
||||
{ 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 0 }, 24, 8, 1, 1 },
|
||||
{ 0, { GLITZ_FOURCC_RGB, 8, 8, 8, 8 }, 24, 8, 1, 1 }
|
||||
};
|
||||
int i;
|
||||
|
||||
|
@ -196,6 +208,9 @@ glitz_drawable_format_copy (const glitz_drawable_format_t *src,
|
|||
if (mask & GLITZ_FORMAT_ID_MASK)
|
||||
dst->id = src->id;
|
||||
|
||||
if (mask & GLITZ_FORMAT_FOURCC_MASK)
|
||||
dst->color.fourcc = src->color.fourcc;
|
||||
|
||||
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
|
||||
dst->color.red_size = src->color.red_size;
|
||||
|
||||
|
@ -234,6 +249,10 @@ glitz_drawable_format_find (glitz_int_drawable_format_t *formats,
|
|||
if (templ->d.id != formats->d.id)
|
||||
continue;
|
||||
|
||||
if (mask & GLITZ_FORMAT_FOURCC_MASK)
|
||||
if (templ->d.color.fourcc != formats->d.color.fourcc)
|
||||
continue;
|
||||
|
||||
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
|
||||
if (templ->d.color.red_size != formats->d.color.red_size)
|
||||
continue;
|
||||
|
@ -300,8 +319,8 @@ _glitz_format_find (glitz_format_t *formats,
|
|||
if (templ->id != formats->id)
|
||||
continue;
|
||||
|
||||
if (mask & GLITZ_FORMAT_TYPE_MASK)
|
||||
if (templ->type != formats->type)
|
||||
if (mask & GLITZ_FORMAT_FOURCC_MASK)
|
||||
if (templ->color.fourcc != formats->color.fourcc)
|
||||
continue;
|
||||
|
||||
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
|
||||
|
@ -345,9 +364,13 @@ glitz_find_standard_format (glitz_drawable_t *drawable,
|
|||
glitz_format_t templ;
|
||||
unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK |
|
||||
GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK |
|
||||
GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK;
|
||||
GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_FOURCC_MASK;
|
||||
|
||||
templ.type = GLITZ_FORMAT_TYPE_COLOR;
|
||||
templ.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
templ.color.red_size = 0;
|
||||
templ.color.green_size = 0;
|
||||
templ.color.blue_size = 0;
|
||||
templ.color.alpha_size = 0;
|
||||
|
||||
switch (format_name) {
|
||||
case GLITZ_STANDARD_ARGB32:
|
||||
|
@ -360,18 +383,11 @@ glitz_find_standard_format (glitz_drawable_t *drawable,
|
|||
templ.color.red_size = 8;
|
||||
templ.color.green_size = 8;
|
||||
templ.color.blue_size = 8;
|
||||
templ.color.alpha_size = 0;
|
||||
break;
|
||||
case GLITZ_STANDARD_A8:
|
||||
templ.color.red_size = 0;
|
||||
templ.color.green_size = 0;
|
||||
templ.color.blue_size = 0;
|
||||
templ.color.alpha_size = 8;
|
||||
break;
|
||||
case GLITZ_STANDARD_A1:
|
||||
templ.color.red_size = 0;
|
||||
templ.color.green_size = 0;
|
||||
templ.color.blue_size = 0;
|
||||
templ.color.alpha_size = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -313,6 +313,19 @@ _glitz_fbo_swap_buffers (void *abstract_drawable)
|
|||
if (!drawable->fb)
|
||||
return 1;
|
||||
|
||||
/* flip */
|
||||
if (drawable->base.back && drawable->base.front)
|
||||
{
|
||||
glitz_texture_t tmp;
|
||||
|
||||
tmp = drawable->base.front->texture;
|
||||
|
||||
drawable->base.front->texture = drawable->base.back->texture;
|
||||
drawable->base.back->texture = tmp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -351,6 +364,50 @@ _glitz_fbo_destroy (void *abstract_drawable)
|
|||
free (drawable);
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_fbo_draw_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer)
|
||||
{
|
||||
glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *)
|
||||
abstract_drawable;
|
||||
|
||||
GLITZ_GL_DRAWABLE (drawable->other);
|
||||
|
||||
switch (buffer) {
|
||||
case GLITZ_GL_FRONT:
|
||||
gl->draw_buffer (GLITZ_GL_COLOR_ATTACHMENT0);
|
||||
break;
|
||||
case GLITZ_GL_BACK:
|
||||
gl->draw_buffer (GLITZ_GL_COLOR_ATTACHMENT1);
|
||||
break;
|
||||
/* TODO: use GL_ARB_draw_buffers
|
||||
case GLITZ_GL_FRONT_AND_BACK:
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_fbo_read_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer)
|
||||
{
|
||||
glitz_fbo_drawable_t *drawable = (glitz_fbo_drawable_t *)
|
||||
abstract_drawable;
|
||||
|
||||
GLITZ_GL_DRAWABLE (drawable->other);
|
||||
|
||||
switch (buffer) {
|
||||
case GLITZ_GL_FRONT:
|
||||
gl->read_buffer (GLITZ_GL_COLOR_ATTACHMENT0);
|
||||
break;
|
||||
case GLITZ_GL_BACK:
|
||||
gl->read_buffer (GLITZ_GL_COLOR_ATTACHMENT1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glitz_drawable_t *
|
||||
_glitz_fbo_drawable_create (glitz_drawable_t *other,
|
||||
glitz_int_drawable_format_t *format,
|
||||
|
@ -377,6 +434,8 @@ _glitz_fbo_drawable_create (glitz_drawable_t *other,
|
|||
backend->detach_notify = _glitz_fbo_detach_notify;
|
||||
backend->swap_buffers = _glitz_fbo_swap_buffers;
|
||||
backend->make_current = _glitz_fbo_make_current;
|
||||
backend->draw_buffer = _glitz_fbo_draw_buffer;
|
||||
backend->read_buffer = _glitz_fbo_read_buffer;
|
||||
|
||||
drawable->fb = 0;
|
||||
|
||||
|
|
|
@ -202,24 +202,25 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t;
|
|||
#define GLITZ_GL_BGR 0x80E0
|
||||
#define GLITZ_GL_BGRA 0x80E1
|
||||
|
||||
#define GLITZ_GL_ALPHA4 0x803B
|
||||
#define GLITZ_GL_ALPHA8 0x803C
|
||||
#define GLITZ_GL_ALPHA12 0x803D
|
||||
#define GLITZ_GL_ALPHA16 0x803E
|
||||
#define GLITZ_GL_R3_G3_B2 0x2A10
|
||||
#define GLITZ_GL_RGB4 0x804F
|
||||
#define GLITZ_GL_RGB5 0x8050
|
||||
#define GLITZ_GL_RGB8 0x8051
|
||||
#define GLITZ_GL_RGB10 0x8052
|
||||
#define GLITZ_GL_RGB12 0x8053
|
||||
#define GLITZ_GL_RGB16 0x8054
|
||||
#define GLITZ_GL_RGBA2 0x8055
|
||||
#define GLITZ_GL_RGBA4 0x8056
|
||||
#define GLITZ_GL_RGB5_A1 0x8057
|
||||
#define GLITZ_GL_RGBA8 0x8058
|
||||
#define GLITZ_GL_RGB10_A2 0x8059
|
||||
#define GLITZ_GL_RGBA12 0x805A
|
||||
#define GLITZ_GL_RGBA16 0x805B
|
||||
#define GLITZ_GL_ALPHA4 0x803B
|
||||
#define GLITZ_GL_ALPHA8 0x803C
|
||||
#define GLITZ_GL_ALPHA12 0x803D
|
||||
#define GLITZ_GL_ALPHA16 0x803E
|
||||
#define GLITZ_GL_LUMINANCE8 0x8040
|
||||
#define GLITZ_GL_R3_G3_B2 0x2A10
|
||||
#define GLITZ_GL_RGB4 0x804F
|
||||
#define GLITZ_GL_RGB5 0x8050
|
||||
#define GLITZ_GL_RGB8 0x8051
|
||||
#define GLITZ_GL_RGB10 0x8052
|
||||
#define GLITZ_GL_RGB12 0x8053
|
||||
#define GLITZ_GL_RGB16 0x8054
|
||||
#define GLITZ_GL_RGBA2 0x8055
|
||||
#define GLITZ_GL_RGBA4 0x8056
|
||||
#define GLITZ_GL_RGB5_A1 0x8057
|
||||
#define GLITZ_GL_RGBA8 0x8058
|
||||
#define GLITZ_GL_RGB10_A2 0x8059
|
||||
#define GLITZ_GL_RGBA12 0x805A
|
||||
#define GLITZ_GL_RGBA16 0x805B
|
||||
|
||||
#define GLITZ_GL_FRONT_AND_BACK 0x0408
|
||||
#define GLITZ_GL_FLAT 0x1D00
|
||||
|
|
|
@ -37,23 +37,10 @@ typedef struct _glitz_gl_pixel_format {
|
|||
glitz_gl_enum_t type;
|
||||
} glitz_gl_pixel_format_t;
|
||||
|
||||
static glitz_gl_pixel_format_t _gl_pixel_formats[] = {
|
||||
static glitz_gl_pixel_format_t _gl_rgb_pixel_formats[] = {
|
||||
{
|
||||
{
|
||||
{
|
||||
8,
|
||||
0x000000ff,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
},
|
||||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
},
|
||||
GLITZ_GL_ALPHA,
|
||||
GLITZ_GL_UNSIGNED_BYTE
|
||||
}, {
|
||||
{
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
32,
|
||||
0xff000000,
|
||||
|
@ -72,12 +59,31 @@ static glitz_gl_pixel_format_t _gl_pixel_formats[] = {
|
|||
GLITZ_GL_UNSIGNED_BYTE
|
||||
#endif
|
||||
|
||||
}, {
|
||||
{
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
8,
|
||||
0x000000ff,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
},
|
||||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
},
|
||||
GLITZ_GL_ALPHA,
|
||||
GLITZ_GL_UNSIGNED_BYTE
|
||||
}
|
||||
};
|
||||
|
||||
static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = {
|
||||
#define N_RGB_FORMATS \
|
||||
(sizeof (_gl_rgb_pixel_formats) / sizeof (glitz_gl_pixel_format_t))
|
||||
|
||||
static glitz_gl_pixel_format_t _gl_packed_rgb_pixel_formats[] = {
|
||||
{
|
||||
{
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
16,
|
||||
0x00000000,
|
||||
|
@ -99,6 +105,31 @@ static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = {
|
|||
}
|
||||
};
|
||||
|
||||
#define N_PACKED_RGB_FORMATS \
|
||||
(sizeof (_gl_packed_rgb_pixel_formats) / sizeof (glitz_gl_pixel_format_t))
|
||||
|
||||
static glitz_gl_pixel_format_t _gl_yuv_pixel_formats[] = {
|
||||
{
|
||||
{
|
||||
GLITZ_FOURCC_YV12,
|
||||
{
|
||||
12,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
},
|
||||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
},
|
||||
GLITZ_GL_LUMINANCE,
|
||||
GLITZ_GL_UNSIGNED_BYTE
|
||||
}
|
||||
};
|
||||
|
||||
#define N_YUV_FORMATS \
|
||||
(sizeof (_gl_yuv_pixel_formats) / sizeof (glitz_gl_pixel_format_t))
|
||||
|
||||
#define SOLID_ALPHA 0
|
||||
#define SOLID_RED 1
|
||||
#define SOLID_GREEN 2
|
||||
|
@ -106,6 +137,7 @@ static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = {
|
|||
|
||||
static glitz_pixel_format_t _solid_format[] = {
|
||||
{
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
16,
|
||||
0x0000ffff,
|
||||
|
@ -116,6 +148,7 @@ static glitz_pixel_format_t _solid_format[] = {
|
|||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
}, {
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
16,
|
||||
0x00000000,
|
||||
|
@ -126,6 +159,7 @@ static glitz_pixel_format_t _solid_format[] = {
|
|||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
}, {
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
16,
|
||||
0x00000000,
|
||||
|
@ -136,6 +170,7 @@ static glitz_pixel_format_t _solid_format[] = {
|
|||
0, 0, 0,
|
||||
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
|
||||
}, {
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
16,
|
||||
0x00000000,
|
||||
|
@ -153,19 +188,19 @@ typedef struct _glitz_pixel_color {
|
|||
} glitz_pixel_color_t;
|
||||
|
||||
typedef struct _glitz_pixel_transform_op {
|
||||
char *line;
|
||||
int offset;
|
||||
char *line, *line2, *line3;
|
||||
int offset;
|
||||
glitz_pixel_format_t *format;
|
||||
glitz_pixel_color_t *color;
|
||||
glitz_pixel_color_t *color;
|
||||
} glitz_pixel_transform_op_t;
|
||||
|
||||
#define FETCH(p, mask) \
|
||||
((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \
|
||||
#define FETCH(p, mask) \
|
||||
((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \
|
||||
0xffffffff) / ((uint64_t) (mask)))): 0x0)
|
||||
|
||||
#define FETCH_A(p, mask) \
|
||||
((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \
|
||||
0xffffffff) /((uint64_t) (mask)))): 0xffffffff)
|
||||
#define FETCH_A(p, mask) \
|
||||
((mask) ? ((uint32_t) ((((uint64_t) (((uint32_t) (p)) & (mask))) * \
|
||||
0xffffffff) / ((uint64_t) (mask)))): 0xffffffff)
|
||||
|
||||
typedef void (*glitz_pixel_fetch_function_t) (glitz_pixel_transform_op_t *op);
|
||||
|
||||
|
@ -237,9 +272,59 @@ _fetch_32 (glitz_pixel_transform_op_t *op)
|
|||
op->color->b = FETCH (p, op->format->masks.blue_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
_fetch_yv12 (glitz_pixel_transform_op_t *op)
|
||||
{
|
||||
int16_t y = ((uint8_t *) op->line)[op->offset] - 16;
|
||||
int16_t v = ((uint8_t *) op->line2)[op->offset >> 1] - 128;
|
||||
int16_t u = ((uint8_t *) op->line3)[op->offset >> 1] - 128;
|
||||
int32_t r, g, b;
|
||||
|
||||
/* TODO: use tables, in a tight loop */
|
||||
op->color->a = 0xffffffff;
|
||||
/* all colors multiplied by 0x010101, cropped, shifted */
|
||||
/* R = 1.164(Y - 16) + 1.596(V - 128) */
|
||||
r = 0x012b27 * y + 0x019a2e * v;
|
||||
op->color->r = r >= 0 ? r < 0x1000000 ? (((unsigned) r) << 8) :
|
||||
0xffffffff : 0;
|
||||
/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
|
||||
g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
|
||||
op->color->g = g >= 0 ? g < 0x1000000 ? (((unsigned) g) << 8) :
|
||||
0xffffffff : 0;
|
||||
/* B = 1.164(Y - 16) + 2.018(U - 128) */
|
||||
b = 0x012b27 * y + 0x0206a2 * u;
|
||||
op->color->b = b >= 0 ? b < 0x1000000 ? (((unsigned) b) << 8) :
|
||||
0xffffffff : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_fetch_yuy2 (glitz_pixel_transform_op_t *op)
|
||||
{
|
||||
int16_t y = ((uint8_t *) op->line)[op->offset << 1] - 16;
|
||||
int16_t u = ((uint8_t *) op->line)[((op->offset << 1) & -4) + 1] - 128;
|
||||
int16_t v = ((uint8_t *) op->line)[((op->offset << 1) & -4) + 3] - 128;
|
||||
int32_t r, g, b;
|
||||
|
||||
/* TODO: use tables, in a tight loop */
|
||||
op->color->a = 0xffffffff;
|
||||
/* all colors multiplied by 0x010101, cropped, shifted */
|
||||
/* R = 1.164(Y - 16) + 1.596(V - 128) */
|
||||
r = 0x012b27 * y + 0x019a2e * v;
|
||||
op->color->r = r >= 0 ? r < 0x1000000 ? (((unsigned) r) << 8) :
|
||||
0xffffffff : 0;
|
||||
/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
|
||||
g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
|
||||
op->color->g = g >= 0 ? g < 0x1000000 ? (((unsigned) g) << 8) :
|
||||
0xffffffff : 0;
|
||||
/* B = 1.164(Y - 16) + 2.018(U - 128) */
|
||||
b = 0x012b27 * y + 0x0206a2 * u;
|
||||
op->color->b = b >= 0 ? b < 0x1000000 ? (((unsigned) b) << 8) :
|
||||
0xffffffff : 0;
|
||||
}
|
||||
|
||||
typedef void (*glitz_pixel_store_function_t) (glitz_pixel_transform_op_t *op);
|
||||
|
||||
#define STORE(v, mask) \
|
||||
#define STORE(v, mask) \
|
||||
(((uint32_t) (((v) * (uint64_t) (mask)) / 0xffffffff)) & (mask))
|
||||
|
||||
static void
|
||||
|
@ -320,15 +405,76 @@ _store_32 (glitz_pixel_transform_op_t *op)
|
|||
STORE (op->color->b, op->format->masks.blue_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
_store_yv12 (glitz_pixel_transform_op_t *op)
|
||||
{
|
||||
uint8_t *yp = &((uint8_t *) op->line)[op->offset];
|
||||
int16_t y;
|
||||
|
||||
/* Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 */
|
||||
y = op->color->r / 0x03e41be4 + op->color->g / 0x01fbefbf +
|
||||
op->color->b / 0x0a343eb2 + 16;
|
||||
|
||||
*yp = y > 0 ? y < 255 ? y : 255 : 0;
|
||||
|
||||
if (op->line2 && (op->offset & 1) == 0)
|
||||
{
|
||||
uint8_t *vp = &((uint8_t *) op->line2)[op->offset >> 1];
|
||||
uint8_t *up = &((uint8_t *) op->line3)[op->offset >> 1];
|
||||
int16_t v, u;
|
||||
|
||||
/* V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 */
|
||||
v = op->color->r / 0x024724bd - op->color->g / 0x02b7a6f5 -
|
||||
op->color->b / 0x0e15a241 + 128;
|
||||
*vp = v > 0 ? v < 255 ? v : 255 : 0;
|
||||
|
||||
/* U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 */
|
||||
u = op->color->b / 0x024724bd - op->color->r / 0x06c1bad0 -
|
||||
op->color->g / 0x36fb99f + 128;
|
||||
|
||||
*up = u > 0 ? u < 255 ? u : 255 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_store_yuy2 (glitz_pixel_transform_op_t *op)
|
||||
{
|
||||
uint8_t *p = (uint8_t *) &op->line[op->offset << 1];
|
||||
int16_t y, v, u;
|
||||
|
||||
/* Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 */
|
||||
y = op->color->r / 0x03e41be4 + op->color->g / 0x01fbefbf +
|
||||
op->color->b / 0x0a343eb2 + 16;
|
||||
|
||||
p[0] = y >= 0 ? y < 255 ? y : 255 : 0;
|
||||
|
||||
if ((op->offset & 1) == 0)
|
||||
{
|
||||
/* U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 */
|
||||
u = op->color->b / 0x024724bd - op->color->r / 0x06c1bad0 -
|
||||
op->color->g / 0x36fb99f + 128;
|
||||
|
||||
p[1] = u >= 0 ? u < 255 ? u : 255 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 */
|
||||
v = op->color->r / 0x024724bd - op->color->g / 0x02b7a6f5 -
|
||||
op->color->b / 0x0e15a241 + 128;
|
||||
|
||||
p[1] = v >= 0 ? v < 255 ? v : 255 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define GLITZ_TRANSFORM_PIXELS_MASK (1L << 0)
|
||||
#define GLITZ_TRANSFORM_SCANLINE_ORDER_MASK (1L << 1)
|
||||
#define GLITZ_TRANSFORM_COPY_BOX_MASK (1L << 2)
|
||||
|
||||
typedef struct _glitz_image {
|
||||
char *data;
|
||||
char *data;
|
||||
glitz_pixel_format_t *format;
|
||||
int width;
|
||||
int height;
|
||||
int width;
|
||||
int height;
|
||||
} glitz_image_t;
|
||||
|
||||
static void
|
||||
|
@ -342,62 +488,111 @@ _glitz_pixel_transform (unsigned long transform,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
int src_stride, dst_stride;
|
||||
int x, y, bytes_per_pixel = 0;
|
||||
int src_stride, dst_stride;
|
||||
int src_planeoffset = 0, dst_planeoffset = 0;
|
||||
int x, y, bytes_per_pixel = 0;
|
||||
glitz_pixel_fetch_function_t fetch;
|
||||
glitz_pixel_store_function_t store;
|
||||
glitz_pixel_color_t color;
|
||||
glitz_pixel_transform_op_t src_op, dst_op;
|
||||
glitz_pixel_color_t color;
|
||||
glitz_pixel_transform_op_t src_op, dst_op;
|
||||
|
||||
switch (src->format->masks.bpp) {
|
||||
case 1:
|
||||
fetch = _fetch_1;
|
||||
switch (src->format->fourcc) {
|
||||
case GLITZ_FOURCC_RGB:
|
||||
switch (src->format->masks.bpp) {
|
||||
case 1:
|
||||
fetch = _fetch_1;
|
||||
break;
|
||||
case 8:
|
||||
fetch = _fetch_8;
|
||||
break;
|
||||
case 16:
|
||||
fetch = _fetch_16;
|
||||
break;
|
||||
case 24:
|
||||
fetch = _fetch_24;
|
||||
break;
|
||||
case 32:
|
||||
default:
|
||||
fetch = _fetch_32;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
fetch = _fetch_8;
|
||||
case GLITZ_FOURCC_YV12:
|
||||
fetch = _fetch_yv12;
|
||||
break;
|
||||
case 16:
|
||||
fetch = _fetch_16;
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
fetch = _fetch_yuy2;
|
||||
break;
|
||||
case 24:
|
||||
fetch = _fetch_24;
|
||||
break;
|
||||
case 32:
|
||||
default:
|
||||
fetch = _fetch_32;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dst->format->masks.bpp) {
|
||||
case 1:
|
||||
store = _store_1;
|
||||
switch (dst->format->fourcc) {
|
||||
case GLITZ_FOURCC_RGB:
|
||||
switch (dst->format->masks.bpp) {
|
||||
case 1:
|
||||
store = _store_1;
|
||||
break;
|
||||
case 8:
|
||||
store = _store_8;
|
||||
break;
|
||||
case 16:
|
||||
store = _store_16;
|
||||
break;
|
||||
case 24:
|
||||
store = _store_24;
|
||||
break;
|
||||
case 32:
|
||||
default:
|
||||
store = _store_32;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
store = _store_8;
|
||||
case GLITZ_FOURCC_YV12:
|
||||
store = _store_yv12;
|
||||
break;
|
||||
case 16:
|
||||
store = _store_16;
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
store = _store_yuy2;
|
||||
break;
|
||||
case 24:
|
||||
store = _store_24;
|
||||
break;
|
||||
case 32:
|
||||
default:
|
||||
store = _store_32;
|
||||
break;
|
||||
}
|
||||
|
||||
src_stride = (src->format->bytes_per_line)? src->format->bytes_per_line:
|
||||
(((src->width * src->format->masks.bpp) / 8) + 3) & -4;
|
||||
switch (src->format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
src_stride = (src->format->bytes_per_line) ?
|
||||
src->format->bytes_per_line: (src->width + 3) & -4;
|
||||
src_planeoffset = src_stride * src->height;
|
||||
bytes_per_pixel = 1;
|
||||
break;
|
||||
default:
|
||||
src_stride = (src->format->bytes_per_line) ?
|
||||
src->format->bytes_per_line:
|
||||
(((src->width * src->format->masks.bpp) / 8) + 3) & -4;
|
||||
/* This only works for bpp % 8 = 0, but it shouldn't be a problem as
|
||||
* it will never be used for bitmaps */
|
||||
bytes_per_pixel = src->format->masks.bpp / 8;
|
||||
}
|
||||
|
||||
if (src_stride == 0)
|
||||
src_stride = 1;
|
||||
|
||||
src_op.format = src->format;
|
||||
src_op.color = &color;
|
||||
|
||||
dst_stride = (dst->format->bytes_per_line)? dst->format->bytes_per_line:
|
||||
(((dst->width * dst->format->masks.bpp) / 8) + 3) & -4;
|
||||
switch (dst->format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
dst_stride = (dst->format->bytes_per_line) ?
|
||||
dst->format->bytes_per_line: (dst->width + 3) & -4;
|
||||
dst_planeoffset = dst_stride * dst->height;
|
||||
break;
|
||||
default:
|
||||
dst_stride = (dst->format->bytes_per_line) ?
|
||||
dst->format->bytes_per_line:
|
||||
(((dst->width * dst->format->masks.bpp) / 8) + 3) & -4;
|
||||
}
|
||||
|
||||
if (dst_stride == 0)
|
||||
dst_stride = 1;
|
||||
|
||||
dst_op.format = dst->format;
|
||||
dst_op.color = &color;
|
||||
|
||||
|
@ -408,7 +603,49 @@ _glitz_pixel_transform (unsigned long transform,
|
|||
else
|
||||
src_op.line = &src->data[(y + y_src) * src_stride];
|
||||
|
||||
dst_op.line = &dst->data[(y + y_dst) * dst_stride];
|
||||
switch (src->format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
if (src->format->scanline_order != dst->format->scanline_order)
|
||||
{
|
||||
src_op.line2 =
|
||||
&src->data[src_planeoffset +
|
||||
(((src->height - (y + y_src) - 1) >> 1))
|
||||
* (src_stride >> 1)];
|
||||
src_op.line3 =
|
||||
&src->data[src_planeoffset +
|
||||
(src_planeoffset >> 2) +
|
||||
(((src->height - (y + y_src) - 1) >> 1))
|
||||
* (src_stride >> 1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
src_op.line2 =
|
||||
&src->data[src_planeoffset +
|
||||
((y + y_src) >> 1) * (src_stride >> 1)];
|
||||
src_op.line3 =
|
||||
&src->data[src_planeoffset +
|
||||
(src_planeoffset >> 2) +
|
||||
((y + y_src) >> 1) * (src_stride >> 1)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dst_op.line = &dst->data[(y + y_dst) * dst_stride];
|
||||
dst_op.line2 = dst_op.line3 = NULL;
|
||||
|
||||
switch (dst->format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
if ((y & 1) == 0)
|
||||
{
|
||||
dst_op.line2 =
|
||||
&dst->data[dst_planeoffset +
|
||||
((y + y_dst) >> 1) * (dst_stride >> 1)];
|
||||
dst_op.line3 =
|
||||
&dst->data[dst_planeoffset + (dst_planeoffset >> 2) +
|
||||
((y + y_dst) >> 1) * (dst_stride >> 1)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (transform & GLITZ_TRANSFORM_PIXELS_MASK)
|
||||
{
|
||||
|
@ -423,41 +660,62 @@ _glitz_pixel_transform (unsigned long transform,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* This only works for bpp >= 8, but it shouldn't be a problem as
|
||||
it will never be used for bitmaps */
|
||||
if (bytes_per_pixel == 0)
|
||||
bytes_per_pixel = src->format->masks.bpp / 8;
|
||||
|
||||
memcpy (&dst_op.line[x_dst * bytes_per_pixel],
|
||||
&src_op.line[x_src * bytes_per_pixel],
|
||||
width * bytes_per_pixel);
|
||||
|
||||
switch (dst->format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
/* Will overwrite color components of adjacent pixels for odd
|
||||
* image sizes or not update color on odd start lines -
|
||||
* who cares? */
|
||||
if ((y & 1) == 0)
|
||||
{
|
||||
memcpy (&dst_op.line2[x_dst >> 1],
|
||||
&src_op.line2[x_src >> 1],
|
||||
width >> 1);
|
||||
memcpy (&dst_op.line3[x_dst >> 1],
|
||||
&src_op.line3[x_src >> 1],
|
||||
width >> 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static glitz_bool_t
|
||||
_glitz_format_match (glitz_pixel_masks_t *masks1,
|
||||
glitz_pixel_masks_t *masks2,
|
||||
unsigned long mask)
|
||||
_glitz_format_match (glitz_pixel_format_t *format1,
|
||||
glitz_pixel_format_t *format2,
|
||||
unsigned long mask)
|
||||
{
|
||||
if (masks1->bpp != masks2->bpp)
|
||||
if (format1->fourcc != format2->fourcc)
|
||||
return 0;
|
||||
|
||||
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
|
||||
if (masks1->red_mask != masks2->red_mask)
|
||||
switch (format1->fourcc) {
|
||||
case GLITZ_FOURCC_RGB:
|
||||
if (format1->masks.bpp != format2->masks.bpp)
|
||||
return 0;
|
||||
|
||||
if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
|
||||
if (masks1->green_mask != masks2->green_mask)
|
||||
return 0;
|
||||
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
|
||||
if (format1->masks.red_mask != format2->masks.red_mask)
|
||||
return 0;
|
||||
|
||||
if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
|
||||
if (masks1->blue_mask != masks2->blue_mask)
|
||||
return 0;
|
||||
if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
|
||||
if (format1->masks.green_mask != format2->masks.green_mask)
|
||||
return 0;
|
||||
|
||||
if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
|
||||
if (masks1->alpha_mask != masks2->alpha_mask)
|
||||
return 0;
|
||||
if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
|
||||
if (format1->masks.blue_mask != format2->masks.blue_mask)
|
||||
return 0;
|
||||
|
||||
if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
|
||||
if (format1->masks.alpha_mask != format2->masks.alpha_mask)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -467,29 +725,32 @@ _glitz_find_gl_pixel_format (glitz_pixel_format_t *format,
|
|||
unsigned long color_mask,
|
||||
unsigned long feature_mask)
|
||||
{
|
||||
int i, n_formats;
|
||||
int i;
|
||||
|
||||
n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t);
|
||||
for (i = 0; i < n_formats; i++)
|
||||
for (i = 0; i < N_RGB_FORMATS; i++)
|
||||
{
|
||||
if (_glitz_format_match (&_gl_pixel_formats[i].pixel.masks,
|
||||
&format->masks, color_mask))
|
||||
return &_gl_pixel_formats[i];
|
||||
if (_glitz_format_match (&_gl_rgb_pixel_formats[i].pixel,
|
||||
format, color_mask))
|
||||
return &_gl_rgb_pixel_formats[i];
|
||||
}
|
||||
|
||||
if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK)
|
||||
{
|
||||
n_formats = sizeof (_gl_packed_pixel_formats) /
|
||||
sizeof (glitz_gl_pixel_format_t);
|
||||
|
||||
for (i = 0; i < n_formats; i++)
|
||||
for (i = 0; i < N_PACKED_RGB_FORMATS; i++)
|
||||
{
|
||||
if (_glitz_format_match (&_gl_packed_pixel_formats[i].pixel.masks,
|
||||
&format->masks, color_mask))
|
||||
return &_gl_packed_pixel_formats[i];
|
||||
if (_glitz_format_match (&_gl_packed_rgb_pixel_formats[i].pixel,
|
||||
format, color_mask))
|
||||
return &_gl_packed_rgb_pixel_formats[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < N_YUV_FORMATS; i++)
|
||||
{
|
||||
if (_glitz_format_match (&_gl_yuv_pixel_formats[i].pixel,
|
||||
format, color_mask))
|
||||
return &_gl_yuv_pixel_formats[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -505,10 +766,10 @@ _component_size (unsigned long mask)
|
|||
}
|
||||
|
||||
static glitz_bool_t
|
||||
_glitz_format_diff (glitz_pixel_masks_t *masks,
|
||||
glitz_color_format_t *pixel_color,
|
||||
glitz_color_format_t *internal_color,
|
||||
int *diff)
|
||||
_glitz_rgb_format_diff (glitz_pixel_masks_t *masks,
|
||||
glitz_color_format_t *pixel_color,
|
||||
glitz_color_format_t *internal_color,
|
||||
int *diff)
|
||||
{
|
||||
int size;
|
||||
|
||||
|
@ -546,48 +807,69 @@ _glitz_find_best_gl_pixel_format (glitz_pixel_format_t *format,
|
|||
glitz_color_format_t *internal_color,
|
||||
unsigned long feature_mask)
|
||||
{
|
||||
glitz_gl_pixel_format_t *best = NULL;
|
||||
glitz_color_format_t color;
|
||||
int i, n_formats, diff, best_diff = MAXSHORT;
|
||||
glitz_gl_pixel_format_t *best = _gl_rgb_pixel_formats;
|
||||
glitz_color_format_t color;
|
||||
int i, diff, best_diff = MAXSHORT;
|
||||
glitz_pixel_masks_t *masks;
|
||||
|
||||
color.red_size = _component_size (format->masks.red_mask);
|
||||
color.green_size = _component_size (format->masks.green_mask);
|
||||
color.blue_size = _component_size (format->masks.blue_mask);
|
||||
color.alpha_size = _component_size (format->masks.alpha_mask);
|
||||
switch (internal_color->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
for (i = 0; i < N_YUV_FORMATS; i++)
|
||||
{
|
||||
glitz_fourcc_t fourcc;
|
||||
|
||||
n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t);
|
||||
for (i = 0; best_diff > 0 && i < n_formats; i++)
|
||||
fourcc = internal_color->fourcc;
|
||||
if (_gl_yuv_pixel_formats[i].pixel.fourcc == fourcc)
|
||||
return &_gl_yuv_pixel_formats[i];
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (format->fourcc) {
|
||||
case GLITZ_FOURCC_RGB:
|
||||
color.red_size = _component_size (format->masks.red_mask);
|
||||
color.green_size = _component_size (format->masks.green_mask);
|
||||
color.blue_size = _component_size (format->masks.blue_mask);
|
||||
color.alpha_size = _component_size (format->masks.alpha_mask);
|
||||
break;
|
||||
case GLITZ_FOURCC_YV12:
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
color.red_size = color.green_size = color.blue_size = 8;
|
||||
color.alpha_size = 0;
|
||||
break;
|
||||
default:
|
||||
color.red_size = color.green_size = color.blue_size =
|
||||
color.alpha_size = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; best_diff > 0 && i < N_RGB_FORMATS; i++)
|
||||
{
|
||||
if (_glitz_format_diff (&_gl_pixel_formats[i].pixel.masks,
|
||||
&color,
|
||||
internal_color,
|
||||
&diff))
|
||||
masks = &_gl_rgb_pixel_formats[i].pixel.masks;
|
||||
if (_glitz_rgb_format_diff (masks, &color, internal_color, &diff))
|
||||
{
|
||||
if (diff < best_diff)
|
||||
{
|
||||
best = &_gl_pixel_formats[i];
|
||||
best = &_gl_rgb_pixel_formats[i];
|
||||
best_diff = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK)
|
||||
{
|
||||
n_formats = sizeof (_gl_packed_pixel_formats) /
|
||||
sizeof (glitz_gl_pixel_format_t);
|
||||
if (!(feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK))
|
||||
return best;
|
||||
|
||||
for (i = 0; best_diff > 0 && i < n_formats; i++)
|
||||
for (i = 0; best_diff > 0 && i < N_PACKED_RGB_FORMATS; i++)
|
||||
{
|
||||
masks = &_gl_packed_rgb_pixel_formats[i].pixel.masks;
|
||||
if (_glitz_rgb_format_diff (masks, &color, internal_color, &diff))
|
||||
{
|
||||
if (_glitz_format_diff (&_gl_packed_pixel_formats[i].pixel.masks,
|
||||
&color,
|
||||
internal_color,
|
||||
&diff))
|
||||
if (diff < best_diff)
|
||||
{
|
||||
if (diff < best_diff)
|
||||
{
|
||||
best = &_gl_packed_pixel_formats[i];
|
||||
best_diff = diff;
|
||||
}
|
||||
best = &_gl_packed_rgb_pixel_formats[i];
|
||||
best_diff = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -652,7 +934,6 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
src_image.data =
|
||||
glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_READ_ONLY);
|
||||
src_image.data += format->skip_lines * format->bytes_per_line;
|
||||
src_image.format = format;
|
||||
src_image.width = src_image.height = 1;
|
||||
|
||||
|
@ -663,7 +944,8 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
_glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK,
|
||||
&src_image, &dst_image,
|
||||
format->xoffset, 0, 0, 0, 1, 1);
|
||||
format->xoffset,format->skip_lines,
|
||||
0, 0, 1, 1);
|
||||
} else
|
||||
dst->solid.alpha = 0xffff;
|
||||
|
||||
|
@ -674,7 +956,8 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
_glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK,
|
||||
&src_image, &dst_image,
|
||||
format->xoffset, 0, 0, 0, 1, 1);
|
||||
format->xoffset,format->skip_lines,
|
||||
0, 0, 1, 1);
|
||||
} else
|
||||
dst->solid.red = 0;
|
||||
|
||||
|
@ -685,7 +968,8 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
_glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK,
|
||||
&src_image, &dst_image,
|
||||
format->xoffset, 0, 0, 0, 1, 1);
|
||||
format->xoffset,format->skip_lines,
|
||||
0, 0, 1, 1);
|
||||
} else
|
||||
dst->solid.green = 0;
|
||||
|
||||
|
@ -696,7 +980,8 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
_glitz_pixel_transform (GLITZ_TRANSFORM_PIXELS_MASK,
|
||||
&src_image, &dst_image,
|
||||
format->xoffset, 0, 0, 0, 1, 1);
|
||||
format->xoffset,format->skip_lines,
|
||||
0, 0, 1, 1);
|
||||
} else
|
||||
dst->solid.blue = 0;
|
||||
|
||||
|
@ -738,9 +1023,11 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
|
||||
/* find direct format */
|
||||
gl_format =
|
||||
_glitz_find_gl_pixel_format (format,
|
||||
color_mask,
|
||||
_glitz_find_gl_pixel_format (format, color_mask,
|
||||
dst->drawable->backend->feature_mask);
|
||||
if (gl_format && gl_format->pixel.fourcc != dst->format->color.fourcc)
|
||||
gl_format = NULL;
|
||||
|
||||
if (gl_format == NULL)
|
||||
{
|
||||
unsigned long feature_mask;
|
||||
|
@ -748,8 +1035,7 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
feature_mask = dst->drawable->backend->feature_mask;
|
||||
transform |= GLITZ_TRANSFORM_PIXELS_MASK;
|
||||
gl_format =
|
||||
_glitz_find_best_gl_pixel_format (format,
|
||||
&dst->format->color,
|
||||
_glitz_find_best_gl_pixel_format (format, &dst->format->color,
|
||||
feature_mask);
|
||||
}
|
||||
|
||||
|
@ -762,7 +1048,7 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
}
|
||||
|
||||
if (height > 1) {
|
||||
if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
|
||||
if (format->scanline_order != gl_format->pixel.scanline_order)
|
||||
transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
|
||||
}
|
||||
|
||||
|
@ -792,11 +1078,25 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
{
|
||||
if (!data)
|
||||
{
|
||||
int stride, bpp;
|
||||
int size;
|
||||
|
||||
bpp = gl_format->pixel.masks.bpp;
|
||||
stride = (((width * bpp) / 8) + 3) & -4;
|
||||
data = malloc (stride * height);
|
||||
switch (gl_format->pixel.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
bytes_per_line = (width + 3) & -4;
|
||||
bytes_per_pixel = 1;
|
||||
size = bytes_per_line * height +
|
||||
bytes_per_line * ((height + 1) >> 1);
|
||||
break;
|
||||
default:
|
||||
bytes_per_line =
|
||||
(((width * gl_format->pixel.masks.bpp) / 8) + 3) &
|
||||
-4;
|
||||
bytes_per_pixel = gl_format->pixel.masks.bpp / 8;
|
||||
size = bytes_per_line * height;
|
||||
break;
|
||||
}
|
||||
|
||||
data = malloc (size);
|
||||
if (!data)
|
||||
{
|
||||
glitz_surface_status_add (dst,
|
||||
|
@ -807,13 +1107,13 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
dst_image.data = pixels = data;
|
||||
dst_image.format = &gl_format->pixel;
|
||||
|
||||
ptr =
|
||||
glitz_buffer_map (buffer,
|
||||
GLITZ_BUFFER_ACCESS_READ_ONLY);
|
||||
ptr = glitz_buffer_map (buffer,
|
||||
GLITZ_BUFFER_ACCESS_READ_ONLY);
|
||||
src_image.format = format;
|
||||
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4);
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH,
|
||||
bytes_per_line / bytes_per_pixel);
|
||||
}
|
||||
|
||||
dst_image.width = box.x2 - box.x1;
|
||||
|
@ -822,13 +1122,13 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
src_image.width = box.x2 - box.x1;
|
||||
src_image.height = box.y2 - box.y1;
|
||||
|
||||
src_image.data = ptr + (format->skip_lines + box.y1 - y_dst) *
|
||||
format->bytes_per_line;
|
||||
src_image.data = ptr;
|
||||
|
||||
_glitz_pixel_transform (transform,
|
||||
&src_image,
|
||||
&dst_image,
|
||||
format->xoffset + box.x1 - x_dst, 0,
|
||||
format->xoffset + box.x1 - x_dst,
|
||||
format->skip_lines + box.y1 - y_dst,
|
||||
0, 0,
|
||||
box.x2 - box.x1, box.y2 - box.y1);
|
||||
}
|
||||
|
@ -840,7 +1140,14 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
GLITZ_GL_PIXEL_UNPACK_BUFFER);
|
||||
|
||||
bytes_per_line = format->bytes_per_line;
|
||||
bytes_per_pixel = format->masks.bpp / 8;
|
||||
switch (format->fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
bytes_per_pixel = 1;
|
||||
break;
|
||||
default:
|
||||
bytes_per_pixel = format->masks.bpp / 8;
|
||||
}
|
||||
|
||||
if (bytes_per_line)
|
||||
{
|
||||
if ((bytes_per_line % 4) == 0)
|
||||
|
@ -868,12 +1175,59 @@ glitz_set_pixels (glitz_surface_t *dst,
|
|||
(format->xoffset + box.x1 - x_dst) * bytes_per_pixel;
|
||||
}
|
||||
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
texture->box.x1 + box.x1,
|
||||
texture->box.y2 - box.y2,
|
||||
box.x2 - box.x1, box.y2 - box.y1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels);
|
||||
switch (gl_format->pixel.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
box.x1,
|
||||
texture->box.y2 - box.y2,
|
||||
box.x2 - box.x1, box.y2 - box.y1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels);
|
||||
|
||||
if ((bytes_per_line % 8) == 0)
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4);
|
||||
else if ((bytes_per_line % 4) == 0)
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2);
|
||||
else
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH,
|
||||
(bytes_per_line / bytes_per_pixel) >> 1);
|
||||
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
(box.x1 >> 1),
|
||||
texture->height - ((box.y2 + 1) >> 1),
|
||||
(box.x2 - box.x1 + 1) >> 1,
|
||||
(box.y2 - box.y1 + 1) >> 1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels + bytes_per_line * height);
|
||||
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
(texture->width >> 1) + (box.x1 >> 1),
|
||||
texture->height - ((box.y2 + 1) >> 1),
|
||||
(box.x2 - box.x1 + 1) >> 1,
|
||||
(box.y2 - box.y1 + 1) >> 1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels + bytes_per_line * height +
|
||||
((bytes_per_line * height) >> 2));
|
||||
break;
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
texture->box.x1 + (box.x1 >> 1),
|
||||
texture->box.y2 - box.y2,
|
||||
(box.x2 - box.x1 + 1) >> 1,
|
||||
box.y2 - box.y1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels);
|
||||
break;
|
||||
default:
|
||||
gl->tex_sub_image_2d (texture->target, 0,
|
||||
texture->box.x1 + box.x1,
|
||||
texture->box.y2 - box.y2,
|
||||
box.x2 - box.x1, box.y2 - box.y1,
|
||||
gl_format->format, gl_format->type,
|
||||
pixels);
|
||||
}
|
||||
|
||||
glitz_surface_damage (dst, &box,
|
||||
GLITZ_DAMAGE_DRAWABLE_MASK |
|
||||
|
@ -1155,7 +1509,7 @@ glitz_get_pixels (glitz_surface_t *src,
|
|||
|
||||
if (from_drawable)
|
||||
{
|
||||
gl->read_buffer (src->buffer);
|
||||
src->drawable->backend->read_buffer (src->drawable, src->buffer);
|
||||
|
||||
gl->disable (GLITZ_GL_SCISSOR_TEST);
|
||||
|
||||
|
|
|
@ -45,24 +45,24 @@
|
|||
#define EXPAND_SRC_DECL "TEMP src;"
|
||||
#define EXPAND_SRC_2D_IN_OP \
|
||||
{ "TXP src, fragment.texcoord[1], texture[1], 2D;", \
|
||||
"DP4 color.a, color, fragment.color;", \
|
||||
"MUL result.color, src, color.a;" }
|
||||
"DP4 color.a, color, fragment.color;", \
|
||||
"MUL result.color, src, color.a;" }
|
||||
|
||||
#define EXPAND_SRC_RECT_IN_OP \
|
||||
{ "TXP src, fragment.texcoord[1], texture[1], RECT;", \
|
||||
"DP4 color.a, color, fragment.color;", \
|
||||
"MUL result.color, src, color.a;" }
|
||||
"DP4 color.a, color, fragment.color;", \
|
||||
"MUL result.color, src, color.a;" }
|
||||
|
||||
#define EXPAND_MASK_DECL "TEMP mask;"
|
||||
#define EXPAND_MASK_2D_IN_OP \
|
||||
{ "TXP mask, fragment.texcoord[0], texture[0], 2D;", \
|
||||
"DP4 mask.a, mask, fragment.color;", \
|
||||
"MUL result.color, color, mask.a;" }
|
||||
#define EXPAND_MASK_2D_IN_OP \
|
||||
{ "TXP mask, fragment.texcoord[0], texture[0], 2D;", \
|
||||
"DP4 mask.a, mask, fragment.color;", \
|
||||
"MUL result.color, color, mask.a;" }
|
||||
|
||||
#define EXPAND_MASK_RECT_IN_OP \
|
||||
{ "TXP mask, fragment.texcoord[0], texture[0], RECT;", \
|
||||
"DP4 mask.a, mask, fragment.color;", \
|
||||
"MUL result.color, color, mask.a;" }
|
||||
"DP4 mask.a, mask, fragment.color;", \
|
||||
"MUL result.color, color, mask.a;" }
|
||||
|
||||
#define EXPAND_IN_NA \
|
||||
{ "NA", "NA", "NA" }
|
||||
|
@ -139,6 +139,18 @@ static const struct _glitz_program_expand_t {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* perspective divide.
|
||||
*/
|
||||
static const char *_perspective_divide[] = {
|
||||
"RCP position.w, pos.w;",
|
||||
"MUL position, pos, position.w;", NULL
|
||||
};
|
||||
|
||||
static const char *_no_perspective_divide[] = {
|
||||
"MOV position, pos;", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* general convolution filter.
|
||||
*/
|
||||
|
@ -148,79 +160,73 @@ static const char *_convolution_header[] = {
|
|||
"TEMP color, in, coord, position;",
|
||||
|
||||
/* extra declarations */
|
||||
"%s"
|
||||
|
||||
/* perspective divide */
|
||||
"RCP position.w, pos.w;",
|
||||
"MUL position, pos, position.w;", NULL
|
||||
"%s", NULL
|
||||
};
|
||||
|
||||
static const char *_convolution_sample_first[] = {
|
||||
"MOV coord, 0.0;",
|
||||
"ADD coord.x, position.x, p[0].x;",
|
||||
"ADD coord.y, position.y, p[0].y;",
|
||||
"ADD coord.xy, position.xyxx, p[0].xyxx;",
|
||||
"TEX in, coord, texture[%s], %s;",
|
||||
"MUL color, in, p[0].z;", NULL
|
||||
};
|
||||
|
||||
static const char *_convolution_sample[] = {
|
||||
"ADD coord.x, position.x, p[%d].x;",
|
||||
"ADD coord.y, position.y, p[%d].y;",
|
||||
"ADD coord.xy, position.xyxx, p[%d].xyxx;",
|
||||
"TEX in, coord, texture[%s], %s;",
|
||||
"MAD color, in, p[%d].z, color;", NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* gradient filters.
|
||||
*/
|
||||
static const char *_gradient_header[] = {
|
||||
"PARAM gradient = program.local[0];",
|
||||
"PARAM stops[%d] = { program.local[1..%d] };",
|
||||
"PARAM gradient[%d] = { program.local[0..%d] };",
|
||||
"PARAM stops[%d] = { program.local[%d..%d] };",
|
||||
"ATTRIB pos = fragment.texcoord[%s];",
|
||||
"TEMP color, second_color, stop0, stop1, position;",
|
||||
|
||||
/* extra declarations */
|
||||
"%s",
|
||||
|
||||
/* perspective divide */
|
||||
"RCP position.w, pos.w;",
|
||||
"MUL position, pos, position.w;", NULL
|
||||
"%s", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* linear gradient filter.
|
||||
*
|
||||
* gradient.x = start offset
|
||||
* gradient.y = 1 / length
|
||||
* gradient.z = cos (angle)
|
||||
* gradient.w = -sin (angle)
|
||||
* gradient.x = a
|
||||
* gradient.y = b
|
||||
* gradient.z = offset
|
||||
*/
|
||||
static const char *_linear_gradient_calculations[] = {
|
||||
"MUL position.x, gradient.z, position.x;",
|
||||
"MAD position.x, gradient.w, position.y, position.x;",
|
||||
"SUB position.z, position.x, gradient.x;",
|
||||
"MUL position.z, position.z, gradient.y;", NULL
|
||||
"MUL position.xy, gradient[0], position;",
|
||||
"ADD position.x, position.x, position.y;",
|
||||
"ADD position.z, position.x, gradient[0].z;", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* radial gradient filter.
|
||||
*
|
||||
* gradient.x = center point X coordinate
|
||||
* gradient.y = center point Y coordinate
|
||||
* gradient.z = radius0
|
||||
* gradient.w = 1 / (radius1 - radius0)
|
||||
* gradient[0].x = fx
|
||||
* gradient[0].y = fy
|
||||
* gradient[0].z = dx
|
||||
* gradient[0].w = dy
|
||||
*
|
||||
* gradient[1].x = m
|
||||
* gradient[1].y = b
|
||||
* gradient[1].z = 4a
|
||||
* gradient[1].w = 1 / 2a
|
||||
*/
|
||||
static const char *_radial_gradient_calculations[] = {
|
||||
"SUB position, position, gradient;",
|
||||
"MUL position.x, position.x, position.x;",
|
||||
"MAD position.x, position.y, position.y, position.x;",
|
||||
"RSQ position.y, position.x;",
|
||||
"RCP position.x, position.y;",
|
||||
"MUL position.x, position.x, position.x;",
|
||||
"MUL position.x, position.x, position.y;",
|
||||
"SUB position.x, position.x, gradient.z;",
|
||||
"MUL position.z, position.x, gradient.w;", NULL
|
||||
"SUB position, position.xyxx, gradient[0].xyxx;",
|
||||
"MUL position.zw, position.xxxy, gradient[0];",
|
||||
"ADD position.w, position.w, position.z;",
|
||||
"MUL position.xyz, position.xyww, position.xyww;",
|
||||
"ADD position.x, position.x, position.y;",
|
||||
"MAD position.z, position.x, gradient[1].z, position.z;",
|
||||
"RSQ position.z, position.z;",
|
||||
"RCP position.z, position.z;",
|
||||
"SUB position.x, position.z, position.w;",
|
||||
"MUL position.x, position.x, gradient[1].w;",
|
||||
"MAD position.z, position.x, gradient[1].x, gradient[1].y;", NULL
|
||||
};
|
||||
|
||||
static const char *_gradient_fill_repeat[] = {
|
||||
|
@ -228,15 +234,12 @@ static const char *_gradient_fill_repeat[] = {
|
|||
};
|
||||
|
||||
static const char *_gradient_fill_reflect[] = {
|
||||
"FLR position.w, position.z;",
|
||||
"MUL position.w, position.w, 0.5;",
|
||||
"FLR position.w, position.w;",
|
||||
"MUL position.y, position.w, 2.0;",
|
||||
"FLR position.x, position.z;",
|
||||
"SUB position.y, position.x, position.y;",
|
||||
"FRC position.x, position.z;",
|
||||
"SUB position.x, position.x, position.y;",
|
||||
"ABS position.z, position.x;", NULL
|
||||
"MUL position.z, position.z, 0.5;"
|
||||
"FRC position.z, position.z;"
|
||||
"MUL position.z, position.z, 2.0;"
|
||||
"SUB position.z, 1.0, position.z;"
|
||||
"ABS position.z, position.z;"
|
||||
"SUB position.z, 1.0, position.z;", NULL
|
||||
};
|
||||
|
||||
static const char *_gradient_init_stops[] = {
|
||||
|
@ -263,7 +266,37 @@ static const char *_gradient_fetch_and_interpolate[] = {
|
|||
"MUL_SAT position.z, position.z, stop0.w;",
|
||||
|
||||
/* linear interpolation */
|
||||
"LRP color, position.z, second_color, color;", NULL
|
||||
"LRP color, position.z, second_color, color;",
|
||||
|
||||
/* multiply alpha */
|
||||
"MUL color.rgb, color.rgba, color.a;", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* color conversion filters
|
||||
*/
|
||||
static const char *_colorspace_yv12_header[] = {
|
||||
"PARAM offset = program.local[0];",
|
||||
"PARAM minmax = program.local[1];",
|
||||
"ATTRIB pos = fragment.texcoord[%s];",
|
||||
"TEMP color, tmp, position;",
|
||||
|
||||
/* extra declarations */
|
||||
"%s", NULL
|
||||
};
|
||||
|
||||
static const char *_colorspace_yv12[] = {
|
||||
"MAX position, position, minmax;",
|
||||
"MIN position, position, minmax.zwww;",
|
||||
"TEX color, position, texture[%s], %s;",
|
||||
"MAD position, position, .5, offset.xyww;",
|
||||
"TEX tmp.x, position, texture[%s], %s;",
|
||||
"MAD color, color, 1.164, -0.073;", /* -1.164 * 16 / 255 */
|
||||
"ADD position.x, position.x, offset.z;",
|
||||
"TEX tmp.y, position, texture[%s], %s;",
|
||||
"SUB tmp, tmp, { .5, .5 };",
|
||||
"MAD color.xyz, { 1.596, -.813, 0 }, tmp.xxxw, color;",
|
||||
"MAD color.xyz, { 0, -.391, 2.018 }, tmp.yyyw, color;", NULL
|
||||
};
|
||||
|
||||
static struct _glitz_program_query {
|
||||
|
@ -276,9 +309,9 @@ static struct _glitz_program_query {
|
|||
{ GLITZ_GL_PROGRAM_NATIVE_INSTRUCTIONS,
|
||||
GLITZ_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS, 1 },
|
||||
{ GLITZ_GL_PROGRAM_PARAMETERS,
|
||||
GLITZ_GL_MAX_PROGRAM_PARAMETERS, 1 },
|
||||
GLITZ_GL_MAX_PROGRAM_PARAMETERS, 0 },
|
||||
{ GLITZ_GL_PROGRAM_NATIVE_PARAMETERS,
|
||||
GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS, 1 },
|
||||
GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS, 0 },
|
||||
{ GLITZ_GL_PROGRAM_ALU_INSTRUCTIONS,
|
||||
GLITZ_GL_MAX_PROGRAM_ALU_INSTRUCTIONS, 0 },
|
||||
{ GLITZ_GL_PROGRAM_TEX_INSTRUCTIONS,
|
||||
|
@ -321,10 +354,10 @@ _glitz_program_under_limits (glitz_gl_proc_address_list_t *gl)
|
|||
|
||||
static glitz_gl_int_t
|
||||
_glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
|
||||
char *program_string,
|
||||
int n_parameters)
|
||||
char *string,
|
||||
int n_parameters)
|
||||
{
|
||||
glitz_gl_int_t error, pid = -1;
|
||||
glitz_gl_int_t error = 0, pid = -1;
|
||||
glitz_gl_uint_t program;
|
||||
|
||||
/* clear error flags */
|
||||
|
@ -334,11 +367,9 @@ _glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
|
|||
gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, program);
|
||||
gl->program_string (GLITZ_GL_FRAGMENT_PROGRAM,
|
||||
GLITZ_GL_PROGRAM_FORMAT_ASCII,
|
||||
strlen (program_string),
|
||||
program_string);
|
||||
strlen (string), string);
|
||||
if (gl->get_error () == GLITZ_GL_NO_ERROR) {
|
||||
gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error);
|
||||
|
||||
if (error == -1) {
|
||||
glitz_gl_int_t value;
|
||||
|
||||
|
@ -358,6 +389,14 @@ _glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error);
|
||||
}
|
||||
if (error != -1)
|
||||
fprintf (stderr, "fp error at pos %d beginning with '%.40s'\n",
|
||||
error, string+error);
|
||||
#endif
|
||||
|
||||
if (pid == -1) {
|
||||
gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0);
|
||||
|
@ -368,7 +407,8 @@ _glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
|
|||
}
|
||||
|
||||
static void
|
||||
_string_array_to_char_array (char *dst, const char *src[])
|
||||
_string_array_to_char_array (char *dst,
|
||||
const char *src[])
|
||||
{
|
||||
int i, n;
|
||||
|
||||
|
@ -387,17 +427,26 @@ _string_array_to_char_array (char *dst, const char *src[])
|
|||
#define GRADIENT_BASE_SIZE 2048
|
||||
#define GRADIENT_STOP_SIZE 256
|
||||
|
||||
#define COLORSPACE_BASE_SIZE 2048
|
||||
|
||||
static glitz_gl_uint_t
|
||||
_glitz_create_fragment_program (glitz_composite_op_t *op,
|
||||
int fp_type,
|
||||
int id,
|
||||
int p_divide,
|
||||
const glitz_program_expand_t *expand)
|
||||
{
|
||||
char buffer[1024], *program = NULL, *tex, *p = NULL;
|
||||
char *texture_type, *extra_declarations;
|
||||
char buffer[1024], *program = NULL, *tex, *p = NULL;
|
||||
char *texture_type, *extra_declarations;
|
||||
const char **pos_to_position;
|
||||
const glitz_in_op_t *in;
|
||||
glitz_gl_uint_t fp;
|
||||
int i;
|
||||
glitz_gl_uint_t fp;
|
||||
int i;
|
||||
|
||||
if (p_divide)
|
||||
pos_to_position = _perspective_divide;
|
||||
else
|
||||
pos_to_position = _no_perspective_divide;
|
||||
|
||||
switch (op->type) {
|
||||
case GLITZ_COMBINE_TYPE_ARGBF:
|
||||
|
@ -438,12 +487,15 @@ _glitz_create_fragment_program (glitz_composite_op_t *op,
|
|||
_string_array_to_char_array (buffer, _convolution_header);
|
||||
p += sprintf (p, buffer, id, id - 1, tex, extra_declarations);
|
||||
|
||||
_string_array_to_char_array (buffer, pos_to_position);
|
||||
p += sprintf (p, buffer);
|
||||
|
||||
_string_array_to_char_array (buffer, _convolution_sample_first);
|
||||
p += sprintf (p, buffer, tex, texture_type);
|
||||
|
||||
_string_array_to_char_array (buffer, _convolution_sample);
|
||||
for (i = 1; i < id; i++)
|
||||
p += sprintf (p, buffer, i, i, tex, texture_type, i);
|
||||
p += sprintf (p, buffer, i, tex, texture_type, i);
|
||||
|
||||
break;
|
||||
case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
|
||||
|
@ -465,17 +517,27 @@ _glitz_create_fragment_program (glitz_composite_op_t *op,
|
|||
p += sprintf (p, "!!ARBfp1.0");
|
||||
|
||||
_string_array_to_char_array (buffer, _gradient_header);
|
||||
p += sprintf (p, buffer, id, id, tex, extra_declarations);
|
||||
|
||||
switch (fp_type) {
|
||||
case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
|
||||
case GLITZ_FP_LINEAR_GRADIENT_NEAREST:
|
||||
case GLITZ_FP_LINEAR_GRADIENT_REPEAT:
|
||||
case GLITZ_FP_LINEAR_GRADIENT_REFLECT:
|
||||
p += sprintf (p, buffer, 1, 0, id, 1, id, tex, extra_declarations);
|
||||
|
||||
_string_array_to_char_array (buffer, pos_to_position);
|
||||
p += sprintf (p, buffer);
|
||||
|
||||
_string_array_to_char_array (buffer,
|
||||
_linear_gradient_calculations);
|
||||
break;
|
||||
default:
|
||||
p += sprintf (p, buffer, 2, 1, id, 2, id + 1, tex,
|
||||
extra_declarations);
|
||||
|
||||
_string_array_to_char_array (buffer, pos_to_position);
|
||||
p += sprintf (p, buffer);
|
||||
|
||||
_string_array_to_char_array (buffer,
|
||||
_radial_gradient_calculations);
|
||||
break;
|
||||
|
@ -514,6 +576,25 @@ _glitz_create_fragment_program (glitz_composite_op_t *op,
|
|||
|
||||
id++;
|
||||
break;
|
||||
case GLITZ_FP_COLORSPACE_YV12:
|
||||
program = malloc (COLORSPACE_BASE_SIZE);
|
||||
if (program == NULL)
|
||||
return 0;
|
||||
|
||||
p = program;
|
||||
|
||||
p += sprintf (p, "!!ARBfp1.0");
|
||||
|
||||
_string_array_to_char_array (buffer, _colorspace_yv12_header);
|
||||
p += sprintf (p, buffer, tex, extra_declarations);
|
||||
|
||||
_string_array_to_char_array (buffer, pos_to_position);
|
||||
p += sprintf (p, buffer);
|
||||
|
||||
_string_array_to_char_array (buffer, _colorspace_yv12);
|
||||
p += sprintf (p, buffer, tex, texture_type, tex, texture_type,
|
||||
tex, texture_type);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -525,8 +606,12 @@ _glitz_create_fragment_program (glitz_composite_op_t *op,
|
|||
if (op->per_component)
|
||||
p += sprintf (p, "%s", in->dot_product);
|
||||
p += sprintf (p, "%s", in->mult);
|
||||
|
||||
sprintf (p, "END");
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "***** fp %d:\n%s\n\n", id, program);
|
||||
#endif
|
||||
fp = _glitz_compile_arb_fragment_program (op->gl, program, id);
|
||||
|
||||
free (program);
|
||||
|
@ -545,22 +630,24 @@ glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
|
|||
glitz_program_map_t *map)
|
||||
{
|
||||
glitz_gl_uint_t program;
|
||||
int i, j, k, x, y;
|
||||
int i, j, k, x, y, z;
|
||||
|
||||
for (i = 0; i < GLITZ_COMBINE_TYPES; i++) {
|
||||
for (j = 0; j < GLITZ_FP_TYPES; j++) {
|
||||
for (x = 0; x < GLITZ_TEXTURE_LAST; x++) {
|
||||
for (y = 0; y < GLITZ_TEXTURE_LAST; y++) {
|
||||
glitz_program_t *p = &map->filters[i][j].fp[x][y];
|
||||
for (z = 0; z < 2; z++) {
|
||||
glitz_program_t *p = &map->filters[i][j].fp[x][y][z];
|
||||
|
||||
if (p->name) {
|
||||
for (k = 0; k < p->size; k++)
|
||||
if (p->name[k] > 0) {
|
||||
program = p->name[k];
|
||||
gl->delete_programs (1, &program);
|
||||
}
|
||||
if (p->name) {
|
||||
for (k = 0; k < p->size; k++)
|
||||
if (p->name[k] > 0) {
|
||||
program = p->name[k];
|
||||
gl->delete_programs (1, &program);
|
||||
}
|
||||
|
||||
free (p->name);
|
||||
free (p->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -583,12 +670,30 @@ glitz_get_fragment_program (glitz_composite_op_t *op,
|
|||
int id)
|
||||
{
|
||||
glitz_program_map_t *map;
|
||||
glitz_program_t *program;
|
||||
int t0 = TEXTURE_INDEX (op->src);
|
||||
int t1 = TEXTURE_INDEX (op->mask);
|
||||
glitz_program_t *program;
|
||||
int t0 = TEXTURE_INDEX (op->src);
|
||||
int t1 = TEXTURE_INDEX (op->mask);
|
||||
int p_divide = 1;
|
||||
|
||||
switch (op->type) {
|
||||
case GLITZ_COMBINE_TYPE_ARGBF:
|
||||
case GLITZ_COMBINE_TYPE_ARGBF_SOLID:
|
||||
case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC:
|
||||
case GLITZ_COMBINE_TYPE_ARGBF_ARGB:
|
||||
case GLITZ_COMBINE_TYPE_ARGBF_ARGBC:
|
||||
if (!SURFACE_PROJECTIVE_TRANSFORM (op->src))
|
||||
p_divide = 0;
|
||||
break;
|
||||
case GLITZ_COMBINE_TYPE_ARGB_ARGBF:
|
||||
case GLITZ_COMBINE_TYPE_SOLID_ARGBF:
|
||||
if (!SURFACE_PROJECTIVE_TRANSFORM (op->mask))
|
||||
p_divide = 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
map = op->dst->drawable->backend->program_map;
|
||||
program = &map->filters[op->type][fp_type].fp[t0][t1];
|
||||
program = &map->filters[op->type][fp_type].fp[t0][t1][p_divide];
|
||||
|
||||
if (program->size < id) {
|
||||
int old_size;
|
||||
|
@ -609,7 +714,7 @@ glitz_get_fragment_program (glitz_composite_op_t *op,
|
|||
glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT);
|
||||
|
||||
program->name[id - 1] =
|
||||
_glitz_create_fragment_program (op, fp_type, id,
|
||||
_glitz_create_fragment_program (op, fp_type, id, p_divide,
|
||||
_program_expand_map[t0][t1]);
|
||||
|
||||
glitz_surface_pop_current (op->dst);
|
||||
|
|
|
@ -144,6 +144,7 @@ glitz_set_rectangles (glitz_surface_t *dst,
|
|||
else
|
||||
{
|
||||
static glitz_pixel_format_t pf = {
|
||||
GLITZ_FOURCC_RGB,
|
||||
{
|
||||
32,
|
||||
0xff000000,
|
||||
|
|
|
@ -90,8 +90,11 @@ glitz_surface_create (glitz_drawable_t *drawable,
|
|||
|
||||
glitz_texture_init (&surface->texture, width, height,
|
||||
drawable->backend->texture_formats[format->id],
|
||||
surface->format->color.fourcc,
|
||||
feature_mask, unnormalized);
|
||||
|
||||
glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0);
|
||||
|
||||
if (width > 64 || height > 64)
|
||||
{
|
||||
glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT);
|
||||
|
@ -205,7 +208,8 @@ _glitz_surface_sync_texture (glitz_surface_t *surface)
|
|||
|
||||
glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
|
||||
|
||||
gl->read_buffer (surface->buffer);
|
||||
surface->drawable->backend->read_buffer (surface->drawable,
|
||||
surface->buffer);
|
||||
|
||||
gl->disable (GLITZ_GL_SCISSOR_TEST);
|
||||
|
||||
|
@ -270,8 +274,8 @@ glitz_surface_sync_drawable (glitz_surface_t *surface)
|
|||
GLITZ_GL_REPLACE);
|
||||
gl->color_4us (0x0, 0x0, 0x0, 0xffff);
|
||||
|
||||
param.filter[0] = param.filter[1] = GLITZ_GL_CLAMP_TO_EDGE;
|
||||
param.wrap[0] = param.wrap[1] = GLITZ_GL_NEAREST;
|
||||
param.filter[0] = param.filter[1] = GLITZ_GL_NEAREST;
|
||||
param.wrap[0] = param.wrap[1] = GLITZ_GL_CLAMP_TO_EDGE;
|
||||
|
||||
glitz_texture_ensure_parameters (gl, texture, ¶m);
|
||||
|
||||
|
@ -470,7 +474,7 @@ _glitz_surface_update_state (glitz_surface_t *surface)
|
|||
drawable->update_all = 0;
|
||||
}
|
||||
|
||||
gl->draw_buffer (surface->buffer);
|
||||
drawable->backend->draw_buffer (drawable, surface->buffer);
|
||||
|
||||
if (SURFACE_DITHER (surface))
|
||||
gl->enable (GLITZ_GL_DITHER);
|
||||
|
@ -490,7 +494,7 @@ glitz_surface_attach (glitz_surface_t *surface,
|
|||
if (surface == drawable->front)
|
||||
return;
|
||||
|
||||
if (surface->format->type != GLITZ_FORMAT_TYPE_COLOR)
|
||||
if (surface->format->color.fourcc != GLITZ_FOURCC_RGB)
|
||||
drawable = NULL;
|
||||
|
||||
if (drawable)
|
||||
|
@ -510,7 +514,7 @@ glitz_surface_attach (glitz_surface_t *surface,
|
|||
if (surface == drawable->back)
|
||||
return;
|
||||
|
||||
if (surface->format->type != GLITZ_FORMAT_TYPE_COLOR)
|
||||
if (surface->format->color.fourcc != GLITZ_FOURCC_RGB)
|
||||
drawable = NULL;
|
||||
|
||||
if (drawable)
|
||||
|
@ -847,13 +851,25 @@ glitz_surface_set_filter (glitz_surface_t *surface,
|
|||
} else {
|
||||
switch (filter) {
|
||||
case GLITZ_FILTER_NEAREST:
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
switch (surface->format->color.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
break;
|
||||
default:
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
}
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
|
||||
break;
|
||||
case GLITZ_FILTER_BILINEAR:
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
switch (surface->format->color.fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
break;
|
||||
default:
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
|
||||
}
|
||||
surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
|
||||
surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
|
||||
|
|
|
@ -34,6 +34,7 @@ glitz_texture_init (glitz_texture_t *texture,
|
|||
int width,
|
||||
int height,
|
||||
glitz_gl_int_t texture_format,
|
||||
glitz_fourcc_t fourcc,
|
||||
unsigned long feature_mask,
|
||||
glitz_bool_t unnormalized)
|
||||
{
|
||||
|
@ -44,24 +45,48 @@ glitz_texture_init (glitz_texture_t *texture,
|
|||
texture->param.border_color.alpha = 0;
|
||||
|
||||
texture->format = texture_format;
|
||||
texture->name = 0;
|
||||
texture->fourcc = fourcc;
|
||||
texture->name = 0;
|
||||
|
||||
if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)
|
||||
{
|
||||
switch (fourcc) {
|
||||
case GLITZ_FOURCC_YV12:
|
||||
/* U and V plane added below */
|
||||
texture->box.x1 = texture->box.y1 = 0;
|
||||
texture->box.x2 = texture->width = width;
|
||||
texture->box.x2 = width;
|
||||
texture->box.y2 = height;
|
||||
texture->width = (width + 1) & ~1;
|
||||
texture->height = (height + 1) & ~1;
|
||||
texture->height += texture->height >> 1;
|
||||
texture->flags = GLITZ_TEXTURE_FLAG_PADABLE_MASK;
|
||||
break;
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
/* 1 RGBA texel for 2 YUY2 pixels */
|
||||
texture->box.x1 = texture->box.y1 = 0;
|
||||
texture->box.x2 = texture->width = width >> 1;
|
||||
texture->box.y2 = texture->height = height;
|
||||
texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
|
||||
texture->flags = GLITZ_TEXTURE_FLAG_CLAMPABLE_MASK |
|
||||
GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
|
||||
GLITZ_TEXTURE_FLAG_PADABLE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture->box.x1 = texture->box.y1 = 1;
|
||||
texture->box.x2 = width + 1;
|
||||
texture->box.y2 = height + 1;
|
||||
texture->width = width + 2;
|
||||
texture->height = height + 2;
|
||||
texture->flags = 0;
|
||||
break;
|
||||
default:
|
||||
if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)
|
||||
{
|
||||
texture->box.x1 = texture->box.y1 = 0;
|
||||
texture->box.x2 = texture->width = width;
|
||||
texture->box.y2 = texture->height = height;
|
||||
texture->flags = GLITZ_TEXTURE_FLAG_CLAMPABLE_MASK |
|
||||
GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
|
||||
GLITZ_TEXTURE_FLAG_PADABLE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture->box.x1 = texture->box.y1 = 1;
|
||||
texture->box.x2 = width + 1;
|
||||
texture->box.y2 = height + 1;
|
||||
texture->width = width + 2;
|
||||
texture->height = height + 2;
|
||||
texture->flags = GLITZ_TEXTURE_FLAG_CLAMPABLE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!unnormalized &&
|
||||
|
@ -154,8 +179,10 @@ glitz_texture_allocate (glitz_gl_proc_address_list_t *gl,
|
|||
|
||||
glitz_texture_bind (gl, texture);
|
||||
|
||||
if (texture->box.x2 != texture->width ||
|
||||
texture->box.y2 != texture->height) {
|
||||
if (TEXTURE_CLAMPABLE (texture) &&
|
||||
(texture->box.x2 != texture->width ||
|
||||
texture->box.y2 != texture->height))
|
||||
{
|
||||
data = malloc (texture->width * texture->height);
|
||||
if (data)
|
||||
memset (data, 0, texture->width * texture->height);
|
||||
|
@ -276,6 +303,7 @@ glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
|
|||
if (flags & GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK)
|
||||
{
|
||||
plane.v[0] = plane.v[2] = 0.0f;
|
||||
|
||||
if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
|
||||
{
|
||||
plane.v[1] = 1.0f;
|
||||
|
@ -284,7 +312,6 @@ glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
|
|||
else
|
||||
{
|
||||
plane.v[1] = -texture->texcoord_height_unit;
|
||||
|
||||
if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
|
||||
plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) *
|
||||
texture->texcoord_height_unit;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static glitz_extension_map gl_extensions[] = {
|
||||
{ 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
|
||||
|
@ -108,14 +109,36 @@ glitz_extensions_query (glitz_gl_float_t version,
|
|||
return mask;
|
||||
}
|
||||
|
||||
static glitz_gl_float_t
|
||||
_glitz_gl_version_string_to_float (const char *gl_version_string)
|
||||
{
|
||||
glitz_gl_float_t version = 0.0f;
|
||||
int i;
|
||||
|
||||
for (i = 0; isdigit (gl_version_string[i]); i++)
|
||||
version = version * 10.0f + (gl_version_string[i] - 48);
|
||||
|
||||
if (gl_version_string[i++] != '.')
|
||||
return 0.0f;
|
||||
|
||||
version = version * 10.0f + (gl_version_string[i] - 48);
|
||||
|
||||
return (version + 0.1f) / 10.0f;
|
||||
}
|
||||
|
||||
static glitz_status_t
|
||||
_glitz_query_gl_extensions (glitz_gl_proc_address_list_t *gl,
|
||||
glitz_gl_float_t *gl_version,
|
||||
unsigned long *feature_mask)
|
||||
{
|
||||
const char *gl_extensions_string;
|
||||
const char *gl_version_string;
|
||||
|
||||
*gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION));
|
||||
gl_version_string = (const char *) gl->get_string (GLITZ_GL_VERSION);
|
||||
if (!gl_version_string)
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
|
||||
*gl_version = _glitz_gl_version_string_to_float (gl_version_string);
|
||||
if (*gl_version < 1.2f)
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
|
||||
|
@ -315,7 +338,8 @@ glitz_backend_init (glitz_backend_t *backend,
|
|||
glitz_create_surface_formats (backend->gl,
|
||||
&backend->formats,
|
||||
&backend->texture_formats,
|
||||
&backend->n_formats);
|
||||
&backend->n_formats,
|
||||
backend->feature_mask);
|
||||
_glitz_add_drawable_formats (backend->gl,
|
||||
backend->feature_mask,
|
||||
&backend->drawable_formats,
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#ifndef GLITZINT_H_INCLUDED
|
||||
#define GLITZINT_H_INCLUDED
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
@ -33,6 +37,25 @@
|
|||
|
||||
#include "glitz.h"
|
||||
|
||||
#if defined(__SVR4) && defined(__sun)
|
||||
# include <sys/int_types.h>
|
||||
#elif defined(_MSC_VER)
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
# if defined(__OpenBSD__)
|
||||
# include <inttypes.h>
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__sun__)
|
||||
# define floorf(a) floor (a)
|
||||
# define ceilf(a) ceil (a)
|
||||
|
@ -230,7 +253,9 @@ typedef int glitz_combine_type_t;
|
|||
#define GLITZ_FP_RADIAL_GRADIENT_NEAREST 6
|
||||
#define GLITZ_FP_RADIAL_GRADIENT_REPEAT 7
|
||||
#define GLITZ_FP_RADIAL_GRADIENT_REFLECT 8
|
||||
#define GLITZ_FP_TYPES 9
|
||||
#define GLITZ_FP_COLORSPACE_YV12 9
|
||||
#define GLITZ_FP_UNSUPPORTED 10
|
||||
#define GLITZ_FP_TYPES 11
|
||||
|
||||
typedef struct _glitz_program_t {
|
||||
glitz_gl_int_t *name;
|
||||
|
@ -238,7 +263,7 @@ typedef struct _glitz_program_t {
|
|||
} glitz_program_t;
|
||||
|
||||
typedef struct _glitz_filter_map_t {
|
||||
glitz_program_t fp[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST];
|
||||
glitz_program_t fp[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST][2];
|
||||
} glitz_filter_map_t;
|
||||
|
||||
typedef struct _glitz_program_map_t {
|
||||
|
@ -382,6 +407,14 @@ typedef struct glitz_backend {
|
|||
(*make_current) (void *drawable,
|
||||
void *context);
|
||||
|
||||
void
|
||||
(*draw_buffer) (void *drawable,
|
||||
const glitz_gl_enum_t buffer);
|
||||
|
||||
void
|
||||
(*read_buffer) (void *drawable,
|
||||
const glitz_gl_enum_t buffer);
|
||||
|
||||
glitz_function_pointer_t
|
||||
(*get_proc_address) (void *context,
|
||||
const char *name);
|
||||
|
@ -430,13 +463,17 @@ typedef struct _glitz_vec4_t {
|
|||
} glitz_vec4_t;
|
||||
|
||||
#define GLITZ_TEXTURE_FLAG_ALLOCATED_MASK (1L << 0)
|
||||
#define GLITZ_TEXTURE_FLAG_REPEATABLE_MASK (1L << 1)
|
||||
#define GLITZ_TEXTURE_FLAG_PADABLE_MASK (1L << 2)
|
||||
#define GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK (1L << 3)
|
||||
#define GLITZ_TEXTURE_FLAG_CLAMPABLE_MASK (1L << 1)
|
||||
#define GLITZ_TEXTURE_FLAG_REPEATABLE_MASK (1L << 2)
|
||||
#define GLITZ_TEXTURE_FLAG_PADABLE_MASK (1L << 3)
|
||||
#define GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK (1L << 4)
|
||||
|
||||
#define TEXTURE_ALLOCATED(texture) \
|
||||
((texture)->flags & GLITZ_TEXTURE_FLAG_ALLOCATED_MASK)
|
||||
|
||||
#define TEXTURE_CLAMPABLE(texture) \
|
||||
((texture)->flags & GLITZ_TEXTURE_FLAG_CLAMPABLE_MASK)
|
||||
|
||||
#define TEXTURE_REPEATABLE(texture) \
|
||||
((texture)->flags & GLITZ_TEXTURE_FLAG_REPEATABLE_MASK)
|
||||
|
||||
|
@ -456,17 +493,18 @@ typedef struct _glitz_texture {
|
|||
glitz_gl_uint_t name;
|
||||
glitz_gl_enum_t target;
|
||||
glitz_gl_int_t format;
|
||||
glitz_fourcc_t fourcc;
|
||||
unsigned long flags;
|
||||
|
||||
glitz_texture_parameters_t param;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
glitz_box_t box;
|
||||
glitz_box_t box;
|
||||
|
||||
glitz_float_t texcoord_width_unit;
|
||||
glitz_float_t texcoord_height_unit;
|
||||
glitz_float_t texcoord_width_unit;
|
||||
glitz_float_t texcoord_height_unit;
|
||||
} glitz_texture_t;
|
||||
|
||||
struct _glitz_texture_object {
|
||||
|
@ -716,7 +754,8 @@ void
|
|||
glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
|
||||
glitz_format_t **formats,
|
||||
glitz_gl_int_t **texture_formats,
|
||||
int *n_formats);
|
||||
int *n_formats,
|
||||
unsigned long features);
|
||||
|
||||
extern void __internal_linkage
|
||||
_glitz_add_drawable_formats (glitz_gl_proc_address_list_t *gl,
|
||||
|
@ -741,6 +780,7 @@ glitz_texture_init (glitz_texture_t *texture,
|
|||
int width,
|
||||
int height,
|
||||
glitz_gl_int_t texture_format,
|
||||
glitz_fourcc_t fourcc,
|
||||
unsigned long feature_mask,
|
||||
glitz_bool_t unnormalized);
|
||||
|
||||
|
@ -907,6 +947,14 @@ _glitz_drawable_init (glitz_drawable_t *drawable,
|
|||
int width,
|
||||
int height);
|
||||
|
||||
void
|
||||
_glitz_drawable_draw_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer);
|
||||
|
||||
void
|
||||
_glitz_drawable_read_buffer (void *abstract_drawable,
|
||||
const glitz_gl_enum_t buffer);
|
||||
|
||||
extern glitz_drawable_t __internal_linkage *
|
||||
_glitz_fbo_drawable_create (glitz_drawable_t *other,
|
||||
glitz_int_drawable_format_t *format,
|
||||
|
@ -1052,5 +1100,7 @@ slim_hidden_proto(glitz_context_set_user_data)
|
|||
slim_hidden_proto(glitz_context_get_proc_address)
|
||||
slim_hidden_proto(glitz_context_make_current)
|
||||
slim_hidden_proto(glitz_context_bind_texture)
|
||||
slim_hidden_proto(glitz_context_draw_buffers)
|
||||
slim_hidden_proto(glitz_context_read_buffer)
|
||||
|
||||
#endif /* GLITZINT_H_INCLUDED */
|
||||
|
|
|
@ -286,6 +286,9 @@ glitz_glx_context_get (glitz_glx_screen_info_t *screen_info,
|
|||
context->backend.make_current = _glitz_glx_make_current;
|
||||
context->backend.get_proc_address = _glitz_glx_context_get_proc_address;
|
||||
|
||||
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
|
||||
context->backend.read_buffer = _glitz_drawable_read_buffer;
|
||||
|
||||
context->backend.drawable_formats = NULL;
|
||||
context->backend.n_drawable_formats = 0;
|
||||
|
||||
|
|
|
@ -216,6 +216,7 @@ glitz_glx_destroy (void *abstract_drawable)
|
|||
GLITZ_CONTEXT_CURRENT);
|
||||
glitz_program_map_fini (drawable->base.backend->gl,
|
||||
&drawable->screen_info->program_map);
|
||||
glitz_program_map_init (&drawable->screen_info->program_map);
|
||||
glitz_glx_pop_current (abstract_drawable);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ _glitz_glx_format_compare (const void *elem1,
|
|||
|
||||
for (; i < 2; i++)
|
||||
{
|
||||
if (format[i]->d.color.fourcc != GLITZ_FOURCC_RGB)
|
||||
score[i] -= 1000;
|
||||
|
||||
if (format[i]->d.color.red_size)
|
||||
{
|
||||
if (format[i]->d.color.red_size >= 8)
|
||||
|
@ -119,8 +122,9 @@ _glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
|
|||
&visual_templ, &num_visuals);
|
||||
|
||||
/* No pbuffers without fbconfigs */
|
||||
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
format.d.id = 0;
|
||||
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
format.d.id = 0;
|
||||
format.d.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
|
||||
for (i = 0; i < num_visuals; i++)
|
||||
{
|
||||
|
@ -243,7 +247,8 @@ _glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info)
|
|||
if (value & GLX_PBUFFER_BIT)
|
||||
format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
|
||||
format.d.id = 0;
|
||||
format.d.id = 0;
|
||||
format.d.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
|
||||
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID,
|
||||
&value);
|
||||
|
|
|
@ -43,8 +43,8 @@ extern "C" {
|
|||
/* glitz_wgl_info.c */
|
||||
|
||||
typedef struct _glitz_wgl_thread_starter_arg_t {
|
||||
int (*user_thread_function) (void *);
|
||||
void *user_thread_function_arg;
|
||||
int (*user_thread_function) (void *);
|
||||
void *user_thread_function_arg;
|
||||
} glitz_wgl_thread_starter_arg_t;
|
||||
|
||||
int
|
||||
|
@ -55,27 +55,32 @@ glitz_wgl_init (const char *gl_library);
|
|||
|
||||
void
|
||||
glitz_wgl_fini (void);
|
||||
|
||||
|
||||
|
||||
|
||||
/* glitz_wgl_format.c */
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_wgl_find_drawable_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
|
||||
glitz_wgl_find_window_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_wgl_find_pbuffer_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count);
|
||||
|
||||
/* glitz_wgl_drawable.c */
|
||||
|
||||
glitz_drawable_t *
|
||||
glitz_wgl_create_drawable_for_window (glitz_drawable_format_t *format,
|
||||
HWND window,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
HWND window,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
glitz_drawable_t *
|
||||
glitz_wgl_create_pbuffer_drawable (glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -45,263 +45,287 @@ _glitz_wgl_context_create (glitz_wgl_screen_info_t *screen_info,
|
|||
int format_id,
|
||||
glitz_wgl_context_t *context)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR dummy_pfd;
|
||||
PIXELFORMATDESCRIPTOR dummy_pfd;
|
||||
|
||||
dummy_pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
dummy_pfd.nVersion = 1;
|
||||
dummy_pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
dummy_pfd.nVersion = 1;
|
||||
|
||||
SetPixelFormat (dc, format_id, &dummy_pfd);
|
||||
SetPixelFormat (dc, format_id, &dummy_pfd);
|
||||
|
||||
context->context = wglCreateContext (dc);
|
||||
context->context = wglCreateContext (dc);
|
||||
|
||||
context->pixel_format = format_id;
|
||||
context->pixel_format = format_id;
|
||||
}
|
||||
|
||||
static glitz_context_t *
|
||||
_glitz_wgl_create_context (void *abstract_drawable,
|
||||
glitz_drawable_format_t *format)
|
||||
glitz_drawable_format_t *format)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_screen_info_t *screen_info = drawable->screen_info;
|
||||
int format_id = screen_info->format_ids[format->id];
|
||||
glitz_wgl_context_t *context;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_screen_info_t *screen_info = drawable->screen_info;
|
||||
int format_id = screen_info->format_ids[format->id];
|
||||
glitz_wgl_context_t *context;
|
||||
|
||||
context = malloc (sizeof (glitz_wgl_context_t));
|
||||
if (!context)
|
||||
return NULL;
|
||||
context = malloc (sizeof (glitz_wgl_context_t));
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
_glitz_context_init (&context->base, &drawable->base);
|
||||
_glitz_context_init (&context->base, &drawable->base);
|
||||
|
||||
_glitz_wgl_context_create (screen_info,
|
||||
drawable->dc,
|
||||
format_id,
|
||||
context);
|
||||
_glitz_wgl_context_create (screen_info,
|
||||
drawable->dc,
|
||||
format_id,
|
||||
context);
|
||||
|
||||
wglShareLists (screen_info->root_context, context->context);
|
||||
wglShareLists (screen_info->root_context, context->context);
|
||||
|
||||
return (glitz_context_t *) context;
|
||||
return (glitz_context_t *) context;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_destroy_context (void *abstract_context)
|
||||
{
|
||||
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
|
||||
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
|
||||
|
||||
wglDeleteContext (context->context);
|
||||
wglDeleteContext (context->context);
|
||||
|
||||
_glitz_context_fini (&context->base);
|
||||
_glitz_context_fini (&context->base);
|
||||
|
||||
free (context);
|
||||
free (context);
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_copy_context (void *abstract_src,
|
||||
void *abstract_dst,
|
||||
unsigned long mask)
|
||||
void *abstract_dst,
|
||||
unsigned long mask)
|
||||
{
|
||||
glitz_wgl_context_t *src = (glitz_wgl_context_t *) abstract_src;
|
||||
glitz_wgl_context_t *dst = (glitz_wgl_context_t *) abstract_dst;
|
||||
glitz_wgl_context_t *src = (glitz_wgl_context_t *) abstract_src;
|
||||
glitz_wgl_context_t *dst = (glitz_wgl_context_t *) abstract_dst;
|
||||
|
||||
wglCopyContext (src->context, dst->context, mask);
|
||||
wglCopyContext (src->context, dst->context, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_make_current (void *abstract_context,
|
||||
void *abstract_drawable)
|
||||
void *abstract_drawable)
|
||||
{
|
||||
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
|
||||
if (wglGetCurrentContext() != context->context ||
|
||||
wglGetCurrentDC() != drawable->dc)
|
||||
{
|
||||
wglMakeCurrent (drawable->dc, context->context);
|
||||
}
|
||||
if (wglGetCurrentContext() != context->context ||
|
||||
wglGetCurrentDC() != drawable->dc)
|
||||
{
|
||||
wglMakeCurrent (drawable->dc, context->context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_notify_dummy (void *abstract_drawable,
|
||||
glitz_surface_t *surface) {}
|
||||
|
||||
static glitz_function_pointer_t
|
||||
_glitz_wgl_context_get_proc_address (void *abstract_context,
|
||||
const char *name)
|
||||
{
|
||||
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *)
|
||||
context->base.drawable;
|
||||
|
||||
/* _glitz_wgl_make_current (drawable, context, NULL); */
|
||||
|
||||
return glitz_wgl_get_proc_address (name, drawable->screen_info);
|
||||
}
|
||||
|
||||
glitz_wgl_context_t *
|
||||
glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
|
||||
HDC dc,
|
||||
glitz_drawable_format_t *format)
|
||||
HDC dc,
|
||||
glitz_drawable_format_t *format)
|
||||
{
|
||||
glitz_wgl_context_t *context;
|
||||
glitz_wgl_context_t **contexts = screen_info->contexts;
|
||||
int index, n_contexts = screen_info->n_contexts;
|
||||
int format_id;
|
||||
glitz_wgl_context_t *context;
|
||||
glitz_wgl_context_t **contexts = screen_info->contexts;
|
||||
int index, n_contexts = screen_info->n_contexts;
|
||||
int format_id;
|
||||
|
||||
for (; n_contexts; n_contexts--, contexts++)
|
||||
if ((*contexts)->pixel_format == screen_info->format_ids[format->id]) {
|
||||
return *contexts;
|
||||
}
|
||||
for (; n_contexts; n_contexts--, contexts++)
|
||||
if ((*contexts)->pixel_format == screen_info->format_ids[format->id])
|
||||
return *contexts;
|
||||
|
||||
index = screen_info->n_contexts++;
|
||||
index = screen_info->n_contexts++;
|
||||
|
||||
screen_info->contexts =
|
||||
realloc (screen_info->contexts,
|
||||
sizeof (glitz_wgl_context_t *) * screen_info->n_contexts);
|
||||
screen_info->contexts =
|
||||
realloc (screen_info->contexts,
|
||||
sizeof (glitz_wgl_context_t *) * screen_info->n_contexts);
|
||||
|
||||
context = malloc (sizeof (glitz_wgl_context_t));
|
||||
context = malloc (sizeof (glitz_wgl_context_t));
|
||||
|
||||
screen_info->contexts[index] = context;
|
||||
screen_info->contexts[index] = context;
|
||||
|
||||
format_id = screen_info->format_ids[format->id];
|
||||
format_id = screen_info->format_ids[format->id];
|
||||
|
||||
_glitz_wgl_context_create (screen_info,
|
||||
dc,
|
||||
format_id,
|
||||
context);
|
||||
_glitz_wgl_context_create (screen_info,
|
||||
dc,
|
||||
format_id,
|
||||
context);
|
||||
|
||||
wglShareLists (screen_info->root_context, context->context);
|
||||
wglShareLists (screen_info->root_context, context->context);
|
||||
|
||||
#if 0
|
||||
/* Not needed as the root_context is created already when the
|
||||
* singleton screen_info is set up.
|
||||
*/
|
||||
if (!screen_info->root_context)
|
||||
screen_info->root_context = context->context;
|
||||
/* Not needed as the root_context is created already when the
|
||||
* singleton screen_info is set up.
|
||||
*/
|
||||
if (!screen_info->root_context)
|
||||
screen_info->root_context = context->context;
|
||||
#endif
|
||||
|
||||
memcpy (&context->backend.gl,
|
||||
&_glitz_wgl_gl_proc_address,
|
||||
sizeof (glitz_gl_proc_address_list_t));
|
||||
context->backend.gl = &_glitz_wgl_gl_proc_address;
|
||||
|
||||
context->backend.create_pbuffer = glitz_wgl_create_pbuffer;
|
||||
context->backend.destroy = glitz_wgl_destroy;
|
||||
context->backend.push_current = glitz_wgl_push_current;
|
||||
context->backend.pop_current = glitz_wgl_pop_current;
|
||||
context->backend.swap_buffers = glitz_wgl_swap_buffers;
|
||||
context->backend.create_pbuffer = glitz_wgl_create_pbuffer;
|
||||
context->backend.destroy = glitz_wgl_destroy;
|
||||
context->backend.push_current = glitz_wgl_push_current;
|
||||
context->backend.pop_current = glitz_wgl_pop_current;
|
||||
context->backend.attach_notify = _glitz_wgl_notify_dummy;
|
||||
context->backend.detach_notify = _glitz_wgl_notify_dummy;
|
||||
context->backend.swap_buffers = glitz_wgl_swap_buffers;
|
||||
|
||||
context->backend.create_context = _glitz_wgl_create_context;
|
||||
context->backend.destroy_context = _glitz_wgl_destroy_context;
|
||||
context->backend.copy_context = _glitz_wgl_copy_context;
|
||||
context->backend.make_current = _glitz_wgl_make_current;
|
||||
context->backend.create_context = _glitz_wgl_create_context;
|
||||
context->backend.destroy_context = _glitz_wgl_destroy_context;
|
||||
context->backend.copy_context = _glitz_wgl_copy_context;
|
||||
context->backend.make_current = _glitz_wgl_make_current;
|
||||
context->backend.get_proc_address = _glitz_wgl_context_get_proc_address;
|
||||
|
||||
context->backend.drawable_formats = screen_info->formats;
|
||||
context->backend.n_drawable_formats = screen_info->n_formats;
|
||||
context->backend.draw_buffer = _glitz_drawable_draw_buffer;
|
||||
context->backend.read_buffer = _glitz_drawable_read_buffer;
|
||||
|
||||
context->backend.texture_formats = NULL;
|
||||
context->backend.formats = NULL;
|
||||
context->backend.n_formats = 0;
|
||||
|
||||
context->backend.program_map = &screen_info->program_map;
|
||||
context->backend.feature_mask = 0;
|
||||
|
||||
context->initialized = 0;
|
||||
|
||||
return context;
|
||||
context->backend.drawable_formats = screen_info->formats;
|
||||
context->backend.n_drawable_formats = screen_info->n_formats;
|
||||
|
||||
context->backend.texture_formats = NULL;
|
||||
context->backend.formats = NULL;
|
||||
context->backend.n_formats = 0;
|
||||
|
||||
context->backend.program_map = &screen_info->program_map;
|
||||
context->backend.feature_mask = 0;
|
||||
|
||||
context->initialized = 0;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_context_destroy (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_wgl_context_t *context)
|
||||
glitz_wgl_context_t *context)
|
||||
{
|
||||
if (context->backend.formats)
|
||||
free (context->backend.formats);
|
||||
if (context->backend.formats)
|
||||
free (context->backend.formats);
|
||||
|
||||
if (context->backend.texture_formats)
|
||||
free (context->backend.texture_formats);
|
||||
if (context->backend.texture_formats)
|
||||
free (context->backend.texture_formats);
|
||||
|
||||
wglDeleteContext (context->context);
|
||||
wglDeleteContext (context->context);
|
||||
|
||||
free (context);
|
||||
free (context);
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_context_initialize (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_wgl_context_t *context)
|
||||
glitz_wgl_context_t *context)
|
||||
{
|
||||
glitz_backend_init (&context->backend,
|
||||
glitz_wgl_get_proc_address,
|
||||
(void *) screen_info);
|
||||
glitz_backend_init (&context->backend,
|
||||
glitz_wgl_get_proc_address,
|
||||
(void *) screen_info);
|
||||
|
||||
context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
|
||||
context->max_viewport_dims);
|
||||
context->backend.gl->get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
|
||||
context->max_viewport_dims);
|
||||
|
||||
glitz_initiate_state (&_glitz_wgl_gl_proc_address);
|
||||
|
||||
context->initialized = 1;
|
||||
glitz_initiate_state (&_glitz_wgl_gl_proc_address);
|
||||
|
||||
context->initialized = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_context_make_current (glitz_wgl_drawable_t *drawable,
|
||||
glitz_bool_t flush)
|
||||
{
|
||||
if (flush)
|
||||
if (flush)
|
||||
{
|
||||
glFlush ();
|
||||
glFlush ();
|
||||
}
|
||||
|
||||
wglMakeCurrent (drawable->dc, drawable->context->context);
|
||||
|
||||
if (!drawable->context->initialized)
|
||||
_glitz_wgl_context_initialize (drawable->screen_info, drawable->context);
|
||||
wglMakeCurrent (drawable->dc, drawable->context->context);
|
||||
|
||||
drawable->base.update_all = 1;
|
||||
|
||||
if (!drawable->context->initialized)
|
||||
_glitz_wgl_context_initialize (drawable->screen_info, drawable->context);
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_context_update (glitz_wgl_drawable_t *drawable,
|
||||
glitz_constraint_t constraint)
|
||||
{
|
||||
HGLRC context;
|
||||
HGLRC context;
|
||||
|
||||
switch (constraint) {
|
||||
case GLITZ_NONE:
|
||||
break;
|
||||
case GLITZ_ANY_CONTEXT_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if (context == NULL)
|
||||
_glitz_wgl_context_make_current (drawable, 0);
|
||||
break;
|
||||
case GLITZ_CONTEXT_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if (context != drawable->context->context)
|
||||
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
|
||||
break;
|
||||
case GLITZ_DRAWABLE_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if ((context != drawable->context->context) ||
|
||||
(wglGetCurrentDC () != drawable->dc))
|
||||
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
|
||||
break;
|
||||
}
|
||||
switch (constraint) {
|
||||
case GLITZ_NONE:
|
||||
break;
|
||||
case GLITZ_ANY_CONTEXT_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if (context == NULL)
|
||||
_glitz_wgl_context_make_current (drawable, 0);
|
||||
break;
|
||||
case GLITZ_CONTEXT_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if (context != drawable->context->context)
|
||||
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
|
||||
break;
|
||||
case GLITZ_DRAWABLE_CURRENT:
|
||||
context = wglGetCurrentContext ();
|
||||
if ((context != drawable->context->context) ||
|
||||
(wglGetCurrentDC () != drawable->dc))
|
||||
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glitz_bool_t
|
||||
glitz_wgl_push_current (void *abstract_drawable,
|
||||
glitz_surface_t *surface,
|
||||
glitz_constraint_t constraint)
|
||||
glitz_surface_t *surface,
|
||||
glitz_constraint_t constraint)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_context_info_t *context_info;
|
||||
int index;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_context_info_t *context_info;
|
||||
int index;
|
||||
|
||||
index = drawable->screen_info->context_stack_size++;
|
||||
index = drawable->screen_info->context_stack_size++;
|
||||
|
||||
context_info = &drawable->screen_info->context_stack[index];
|
||||
context_info->drawable = drawable;
|
||||
context_info->surface = surface;
|
||||
context_info->constraint = constraint;
|
||||
|
||||
_glitz_wgl_context_update (context_info->drawable, constraint);
|
||||
context_info = &drawable->screen_info->context_stack[index];
|
||||
context_info->drawable = drawable;
|
||||
context_info->surface = surface;
|
||||
context_info->constraint = constraint;
|
||||
|
||||
_glitz_wgl_context_update (context_info->drawable, constraint);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
glitz_surface_t *
|
||||
glitz_wgl_pop_current (void *abstract_drawable)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_context_info_t *context_info = NULL;
|
||||
int index;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_context_info_t *context_info = NULL;
|
||||
int index;
|
||||
|
||||
drawable->screen_info->context_stack_size--;
|
||||
index = drawable->screen_info->context_stack_size - 1;
|
||||
drawable->screen_info->context_stack_size--;
|
||||
index = drawable->screen_info->context_stack_size - 1;
|
||||
|
||||
context_info = &drawable->screen_info->context_stack[index];
|
||||
context_info = &drawable->screen_info->context_stack[index];
|
||||
|
||||
if (context_info->drawable)
|
||||
_glitz_wgl_context_update (context_info->drawable,
|
||||
context_info->constraint);
|
||||
|
||||
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
|
||||
return context_info->surface;
|
||||
|
||||
return NULL;
|
||||
if (context_info->drawable)
|
||||
_glitz_wgl_context_update (context_info->drawable,
|
||||
context_info->constraint);
|
||||
|
||||
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
|
||||
return context_info->surface;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -39,184 +39,190 @@
|
|||
glitz_status_t
|
||||
glitz_wgl_make_current_read (void *abstract_surface)
|
||||
{
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static glitz_wgl_drawable_t *
|
||||
_glitz_wgl_create_drawable (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_wgl_context_t *context,
|
||||
glitz_drawable_format_t *format,
|
||||
glitz_wgl_context_t *context,
|
||||
glitz_drawable_format_t *format,
|
||||
HWND window,
|
||||
HDC dc,
|
||||
HPBUFFERARB pbuffer,
|
||||
int width,
|
||||
int height)
|
||||
HDC dc,
|
||||
HPBUFFERARB pbuffer,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return NULL;
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
|
||||
drawable = (glitz_wgl_drawable_t *) malloc (sizeof (glitz_wgl_drawable_t));
|
||||
if (drawable == NULL)
|
||||
return NULL;
|
||||
if (width <= 0 || height <= 0)
|
||||
return NULL;
|
||||
|
||||
drawable->base.ref_count = 1;
|
||||
drawable->screen_info = screen_info;
|
||||
drawable->context = context;
|
||||
drawable->window = window;
|
||||
drawable->dc = dc;
|
||||
drawable->pbuffer = pbuffer;
|
||||
drawable->base.format = format;
|
||||
drawable->base.backend = &context->backend;
|
||||
drawable = (glitz_wgl_drawable_t *) malloc (sizeof (glitz_wgl_drawable_t));
|
||||
if (drawable == NULL)
|
||||
return NULL;
|
||||
|
||||
glitz_drawable_update_size (&drawable->base, width, height);
|
||||
drawable->base.ref_count = 1;
|
||||
drawable->screen_info = screen_info;
|
||||
drawable->context = context;
|
||||
drawable->window = window;
|
||||
drawable->dc = dc;
|
||||
drawable->pbuffer = pbuffer;
|
||||
|
||||
if (!context->initialized) {
|
||||
glitz_wgl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
|
||||
glitz_wgl_pop_current (drawable);
|
||||
}
|
||||
|
||||
if (width > context->max_viewport_dims[0] ||
|
||||
height > context->max_viewport_dims[1]) {
|
||||
free (drawable);
|
||||
return NULL;
|
||||
}
|
||||
_glitz_drawable_init (&drawable->base,
|
||||
&screen_info->formats[format->id],
|
||||
&context->backend,
|
||||
width,
|
||||
height);
|
||||
|
||||
screen_info->drawables++;
|
||||
|
||||
return drawable;
|
||||
if (!context->initialized) {
|
||||
glitz_wgl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
|
||||
glitz_wgl_pop_current (drawable);
|
||||
}
|
||||
|
||||
if (width > context->max_viewport_dims[0] ||
|
||||
height > context->max_viewport_dims[1]) {
|
||||
free (drawable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen_info->drawables++;
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
static glitz_drawable_t *
|
||||
_glitz_wgl_create_pbuffer_drawable (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
glitz_wgl_context_t *context;
|
||||
HPBUFFERARB pbuffer;
|
||||
HDC dc;
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
glitz_wgl_context_t *context;
|
||||
glitz_int_drawable_format_t *iformat = &screen_info->formats[format->id];
|
||||
HPBUFFERARB pbuffer;
|
||||
HDC dc;
|
||||
|
||||
if (!format->types.pbuffer)
|
||||
return NULL;
|
||||
if (!(iformat->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK))
|
||||
return NULL;
|
||||
|
||||
pbuffer = glitz_wgl_pbuffer_create (screen_info, screen_info->format_ids[format->id],
|
||||
width, height,
|
||||
&dc);
|
||||
if (!pbuffer)
|
||||
return NULL;
|
||||
|
||||
context = glitz_wgl_context_get (screen_info, dc, format);
|
||||
if (!context) {
|
||||
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
|
||||
return NULL;
|
||||
}
|
||||
pbuffer = glitz_wgl_pbuffer_create (screen_info, screen_info->format_ids[format->id],
|
||||
width, height,
|
||||
&dc);
|
||||
if (!pbuffer)
|
||||
return NULL;
|
||||
|
||||
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
|
||||
NULL, dc, pbuffer,
|
||||
width, height);
|
||||
if (!drawable) {
|
||||
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
|
||||
glitz_wgl_context_destroy (screen_info, context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &drawable->base;
|
||||
context = glitz_wgl_context_get (screen_info, dc, format);
|
||||
if (!context) {
|
||||
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
|
||||
NULL, dc, pbuffer,
|
||||
width, height);
|
||||
if (!drawable) {
|
||||
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
|
||||
glitz_wgl_context_destroy (screen_info, context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &drawable->base;
|
||||
}
|
||||
|
||||
glitz_drawable_t *
|
||||
glitz_wgl_create_pbuffer (void *abstract_templ,
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
glitz_wgl_drawable_t *templ = (glitz_wgl_drawable_t *) abstract_templ;
|
||||
glitz_wgl_drawable_t *templ = (glitz_wgl_drawable_t *) abstract_templ;
|
||||
|
||||
return _glitz_wgl_create_pbuffer_drawable (templ->screen_info, format,
|
||||
width, height);
|
||||
return _glitz_wgl_create_pbuffer_drawable (templ->screen_info, format,
|
||||
width, height);
|
||||
}
|
||||
|
||||
glitz_drawable_t *
|
||||
glitz_wgl_create_drawable_for_window (glitz_drawable_format_t *format,
|
||||
HWND window,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
HWND window,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
glitz_wgl_screen_info_t *screen_info;
|
||||
glitz_wgl_context_t *context;
|
||||
HDC dc;
|
||||
glitz_wgl_drawable_t *drawable;
|
||||
glitz_wgl_screen_info_t *screen_info;
|
||||
glitz_wgl_context_t *context;
|
||||
HDC dc;
|
||||
|
||||
screen_info = glitz_wgl_screen_info_get ();
|
||||
if (!screen_info)
|
||||
return NULL;
|
||||
|
||||
dc = GetDC (window);
|
||||
screen_info = glitz_wgl_screen_info_get ();
|
||||
if (!screen_info)
|
||||
return NULL;
|
||||
|
||||
context = glitz_wgl_context_get (screen_info, dc, format);
|
||||
if (!context) {
|
||||
ReleaseDC (window, dc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
|
||||
window, dc, NULL,
|
||||
width, height);
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
dc = GetDC (window);
|
||||
|
||||
return &drawable->base;
|
||||
context = glitz_wgl_context_get (screen_info, dc, format);
|
||||
if (!context) {
|
||||
ReleaseDC (window, dc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
|
||||
window, dc, NULL,
|
||||
width, height);
|
||||
if (!drawable)
|
||||
return NULL;
|
||||
|
||||
return &drawable->base;
|
||||
}
|
||||
|
||||
glitz_drawable_t *
|
||||
glitz_wgl_create_pbuffer_drawable (glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
glitz_wgl_screen_info_t *screen_info;
|
||||
glitz_wgl_screen_info_t *screen_info;
|
||||
|
||||
screen_info = glitz_wgl_screen_info_get ();
|
||||
if (!screen_info)
|
||||
return NULL;
|
||||
screen_info = glitz_wgl_screen_info_get ();
|
||||
if (!screen_info)
|
||||
return NULL;
|
||||
|
||||
return _glitz_wgl_create_pbuffer_drawable (screen_info, format,
|
||||
width, height);
|
||||
return _glitz_wgl_create_pbuffer_drawable (screen_info, format,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_destroy (void *abstract_drawable)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
|
||||
drawable->screen_info->drawables--;
|
||||
if (drawable->screen_info->drawables == 0) {
|
||||
/*
|
||||
* Last drawable? We have to destroy all fragment programs as this may
|
||||
* be our last chance to have a context current.
|
||||
*/
|
||||
glitz_wgl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
|
||||
glitz_program_map_fini (&drawable->base.backend->gl,
|
||||
&drawable->screen_info->program_map);
|
||||
glitz_wgl_pop_current (abstract_drawable);
|
||||
}
|
||||
|
||||
if (wglGetCurrentDC () == drawable->dc)
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
drawable->screen_info->drawables--;
|
||||
if (drawable->screen_info->drawables == 0) {
|
||||
/*
|
||||
* Last drawable? We have to destroy all fragment programs as this may
|
||||
* be our last chance to have a context current.
|
||||
*/
|
||||
glitz_wgl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
|
||||
glitz_program_map_fini (drawable->base.backend->gl,
|
||||
&drawable->screen_info->program_map);
|
||||
glitz_program_map_init (&drawable->screen_info->program_map);
|
||||
glitz_wgl_pop_current (abstract_drawable);
|
||||
}
|
||||
|
||||
if (drawable->pbuffer)
|
||||
glitz_wgl_pbuffer_destroy (drawable->screen_info, drawable->pbuffer, drawable->dc);
|
||||
|
||||
free (drawable);
|
||||
|
||||
if (wglGetCurrentDC () == drawable->dc)
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
if (drawable->pbuffer)
|
||||
glitz_wgl_pbuffer_destroy (drawable->screen_info, drawable->pbuffer, drawable->dc);
|
||||
|
||||
free (drawable);
|
||||
}
|
||||
|
||||
void
|
||||
glitz_bool_t
|
||||
glitz_wgl_swap_buffers (void *abstract_drawable)
|
||||
{
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
|
||||
|
||||
SwapBuffers (drawable->dc);
|
||||
SwapBuffers (drawable->dc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -38,45 +38,46 @@
|
|||
#include <ctype.h>
|
||||
|
||||
static glitz_extension_map wgl_extensions[] = {
|
||||
{ 0.0, "WGL_ARB_pixel_format", GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK },
|
||||
{ 0.0, "WGL_ARB_pbuffer", GLITZ_WGL_FEATURE_PBUFFER_MASK },
|
||||
{ 0.0, "WGL_ARB_make_current_read",
|
||||
GLITZ_WGL_FEATURE_MAKE_CURRENT_READ_MASK },
|
||||
{ 0.0, "WGL_ARB_multisample", GLITZ_WGL_FEATURE_MULTISAMPLE_MASK },
|
||||
{ 0.0, NULL, 0 }
|
||||
{ 0.0, "WGL_ARB_pixel_format", GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK },
|
||||
{ 0.0, "WGL_ARB_pbuffer", GLITZ_WGL_FEATURE_PBUFFER_MASK },
|
||||
{ 0.0, "WGL_ARB_make_current_read",
|
||||
GLITZ_WGL_FEATURE_MAKE_CURRENT_READ_MASK },
|
||||
{ 0.0, "WGL_ARB_multisample", GLITZ_WGL_FEATURE_MULTISAMPLE_MASK },
|
||||
{ 0.0, NULL, 0 }
|
||||
};
|
||||
|
||||
void
|
||||
glitz_wgl_query_extensions (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_gl_float_t wgl_version)
|
||||
{
|
||||
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
||||
const char *wgl_extensions_string;
|
||||
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
||||
const char *wgl_extensions_string;
|
||||
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress ("wglGetExtensionsStringARB");
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||
wglGetProcAddress ("wglGetExtensionsStringARB");
|
||||
|
||||
if (wglGetExtensionsStringARB == NULL)
|
||||
return;
|
||||
if (wglGetExtensionsStringARB == NULL)
|
||||
return;
|
||||
|
||||
wgl_extensions_string = (*wglGetExtensionsStringARB) (screen_info->root_dc);
|
||||
|
||||
screen_info->wgl_feature_mask =
|
||||
glitz_extensions_query (wgl_version,
|
||||
wgl_extensions_string,
|
||||
wgl_extensions);
|
||||
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
|
||||
const char *renderer;
|
||||
wgl_extensions_string = (*wglGetExtensionsStringARB) (screen_info->root_dc);
|
||||
|
||||
renderer = glGetString (GL_RENDERER);
|
||||
if (renderer) {
|
||||
|
||||
/* nVIDIA's driver seem to support multisample with pbuffers (?) */
|
||||
if (!strncmp ("GeForce", renderer, 7) ||
|
||||
!strncmp ("Quadro", renderer, 6))
|
||||
screen_info->wgl_feature_mask |=
|
||||
GLITZ_WGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
|
||||
screen_info->wgl_feature_mask =
|
||||
glitz_extensions_query (wgl_version,
|
||||
wgl_extensions_string,
|
||||
wgl_extensions);
|
||||
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
|
||||
const char *renderer;
|
||||
|
||||
renderer = glGetString (GL_RENDERER);
|
||||
if (renderer) {
|
||||
|
||||
/* nVIDIA's driver seem to support multisample with pbuffers (?) */
|
||||
if (!strncmp ("GeForce", renderer, 7) ||
|
||||
!strncmp ("Quadro", renderer, 6))
|
||||
screen_info->wgl_feature_mask |=
|
||||
GLITZ_WGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -40,308 +40,324 @@
|
|||
|
||||
static int
|
||||
_glitz_wgl_format_compare (const void *elem1,
|
||||
const void *elem2)
|
||||
const void *elem2)
|
||||
{
|
||||
int i, score[2];
|
||||
glitz_drawable_format_t *format[2];
|
||||
|
||||
format[0] = (glitz_drawable_format_t *) elem1;
|
||||
format[1] = (glitz_drawable_format_t *) elem2;
|
||||
i = score[0] = score[1] = 0;
|
||||
glitz_int_drawable_format_t *format[2];
|
||||
int i, score[2];
|
||||
|
||||
for (; i < 2; i++) {
|
||||
if (format[i]->color.red_size) {
|
||||
if (format[i]->color.red_size == 8)
|
||||
score[i] += 5;
|
||||
score[i] += 10;
|
||||
format[0] = (glitz_int_drawable_format_t *) elem1;
|
||||
format[1] = (glitz_int_drawable_format_t *) elem2;
|
||||
i = score[0] = score[1] = 0;
|
||||
|
||||
for (; i < 2; i++)
|
||||
{
|
||||
if (format[i]->d.color.fourcc != GLITZ_FOURCC_RGB)
|
||||
score[i] -= 1000;
|
||||
|
||||
if (format[i]->d.color.red_size)
|
||||
{
|
||||
if (format[i]->d.color.red_size >= 8)
|
||||
score[i] += 5;
|
||||
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->d.color.alpha_size)
|
||||
{
|
||||
if (format[i]->d.color.alpha_size >= 8)
|
||||
score[i] += 5;
|
||||
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->d.stencil_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->d.depth_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->d.doublebuffer)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->d.samples > 1)
|
||||
score[i] -= (20 - format[i]->d.samples);
|
||||
|
||||
if (format[i]->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->caveat)
|
||||
score[i] -= format[i]->caveat * 500;
|
||||
}
|
||||
|
||||
if (format[i]->color.green_size) {
|
||||
if (format[i]->color.green_size == 8)
|
||||
score[i] += 5;
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->color.alpha_size) {
|
||||
if (format[i]->color.alpha_size == 8)
|
||||
score[i] += 5;
|
||||
score[i] += 10;
|
||||
}
|
||||
|
||||
if (format[i]->stencil_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->depth_size)
|
||||
score[i] += 5;
|
||||
|
||||
if (format[i]->doublebuffer)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->types.window)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->types.pbuffer)
|
||||
score[i] += 10;
|
||||
|
||||
if (format[i]->samples > 1)
|
||||
score[i] -= (20 - format[i]->samples);
|
||||
}
|
||||
|
||||
return score[1] - score[0];
|
||||
return score[1] - score[0];
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_add_format (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_drawable_format_t *format,
|
||||
int id)
|
||||
_glitz_add_format (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_int_drawable_format_t *format,
|
||||
int id)
|
||||
{
|
||||
if (!glitz_drawable_format_find (screen_info->formats,
|
||||
screen_info->n_formats,
|
||||
GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK,
|
||||
format, 0)) {
|
||||
int n = screen_info->n_formats;
|
||||
|
||||
screen_info->formats =
|
||||
realloc (screen_info->formats,
|
||||
sizeof (glitz_drawable_format_t) * (n + 1));
|
||||
screen_info->format_ids =
|
||||
realloc (screen_info->format_ids, sizeof (int) * (n + 1));
|
||||
|
||||
if (screen_info->formats && screen_info->format_ids) {
|
||||
screen_info->formats[n] = *format;
|
||||
screen_info->formats[n].id = n;
|
||||
screen_info->format_ids[n] = id;
|
||||
screen_info->n_formats++;
|
||||
screen_info->format_ids =
|
||||
realloc (screen_info->format_ids,
|
||||
sizeof (int) * (n + 1));
|
||||
screen_info->formats =
|
||||
realloc (screen_info->formats,
|
||||
sizeof (glitz_int_drawable_format_t) * (n + 1));
|
||||
if (screen_info->format_ids && screen_info->formats)
|
||||
{
|
||||
screen_info->formats[n] = *format;
|
||||
screen_info->formats[n].d.id = n;
|
||||
screen_info->format_ids[n] = id;
|
||||
screen_info->n_formats++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static glitz_bool_t
|
||||
_glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
glitz_drawable_format_t format;
|
||||
int i, num_pixel_formats;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
glitz_int_drawable_format_t format;
|
||||
int i, num_pixel_formats;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
num_pixel_formats =
|
||||
DescribePixelFormat (screen_info->root_dc, 1,
|
||||
sizeof (PIXELFORMATDESCRIPTOR), &pfd);
|
||||
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
|
||||
if (!num_pixel_formats)
|
||||
return 0;
|
||||
num_pixel_formats =
|
||||
DescribePixelFormat (screen_info->root_dc, 1,
|
||||
sizeof (PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
for (i = 1; i <= num_pixel_formats; i++) {
|
||||
format.id = 0;
|
||||
if (!num_pixel_formats)
|
||||
return 0;
|
||||
|
||||
if (!DescribePixelFormat (screen_info->root_dc, i,
|
||||
sizeof (PIXELFORMATDESCRIPTOR), &pfd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (i = 1; i <= num_pixel_formats; i++) {
|
||||
format.d.id = 0;
|
||||
format.caveat = 0;
|
||||
format.types = 0;
|
||||
|
||||
if (!((pfd.dwFlags & PFD_DRAW_TO_WINDOW) &&
|
||||
(pfd.dwFlags & PFD_SUPPORT_OPENGL)))
|
||||
continue;
|
||||
if (!DescribePixelFormat (screen_info->root_dc, i,
|
||||
sizeof (PIXELFORMATDESCRIPTOR), &pfd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pfd.iPixelType != PFD_TYPE_RGBA)
|
||||
continue;
|
||||
|
||||
if (pfd.dwFlags & (PFD_NEED_PALETTE |
|
||||
PFD_NEED_SYSTEM_PALETTE |
|
||||
PFD_STEREO))
|
||||
continue;
|
||||
|
||||
#ifndef USE_MESA
|
||||
/* Can't use the Windows software implementation as glitz
|
||||
* unconditionally requires OpenGL 1.2, and it's only 1.1.
|
||||
*/
|
||||
if (pfd.dwFlags & PFD_GENERIC_FORMAT)
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
printf ("Pixel format %d Flags: 0x%08x\n", i, pfd.dwFlags);
|
||||
#endif
|
||||
|
||||
format.types.window = 1;
|
||||
format.types.pbuffer = 0;
|
||||
if (!((pfd.dwFlags & PFD_DRAW_TO_WINDOW) &&
|
||||
(pfd.dwFlags & PFD_SUPPORT_OPENGL)))
|
||||
continue;
|
||||
|
||||
format.color.red_size = pfd.cRedBits;
|
||||
format.color.green_size = pfd.cGreenBits;
|
||||
format.color.blue_size = pfd.cBlueBits;
|
||||
format.color.alpha_size = pfd.cAlphaBits;
|
||||
if (pfd.iPixelType != PFD_TYPE_RGBA)
|
||||
continue;
|
||||
|
||||
format.depth_size = pfd.cDepthBits;
|
||||
format.stencil_size = pfd.cStencilBits;
|
||||
if (pfd.dwFlags & (PFD_NEED_PALETTE |
|
||||
PFD_NEED_SYSTEM_PALETTE |
|
||||
PFD_STEREO))
|
||||
continue;
|
||||
|
||||
format.doublebuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0;
|
||||
|
||||
format.samples = 1;
|
||||
#ifndef USE_MESA
|
||||
/* Can't use the Windows software implementation as glitz
|
||||
* unconditionally requires OpenGL 1.2, and it's only 1.1.
|
||||
*/
|
||||
if (pfd.dwFlags & PFD_GENERIC_FORMAT)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
_glitz_add_format (screen_info, &format, i);
|
||||
}
|
||||
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
|
||||
return 0;
|
||||
format.d.color.red_size = pfd.cRedBits;
|
||||
format.d.color.green_size = pfd.cGreenBits;
|
||||
format.d.color.blue_size = pfd.cBlueBits;
|
||||
format.d.color.alpha_size = pfd.cAlphaBits;
|
||||
format.d.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
|
||||
format.d.depth_size = pfd.cDepthBits;
|
||||
format.d.stencil_size = pfd.cStencilBits;
|
||||
|
||||
format.d.doublebuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0;
|
||||
|
||||
format.d.samples = 1;
|
||||
|
||||
_glitz_add_format (screen_info, &format, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static glitz_status_t
|
||||
_glitz_wgl_query_formats_using_pixel_format (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
glitz_drawable_format_t format;
|
||||
int i, num_pixel_formats;
|
||||
int question, answer;
|
||||
glitz_wgl_static_proc_address_list_t *wgl = &screen_info->wgl;
|
||||
|
||||
question = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, 0, 0, 1,
|
||||
&question, &num_pixel_formats)) {
|
||||
/* wglGetPixelFormatAttribivARB didn't work, fall back to
|
||||
* DescribePixelFormat.
|
||||
*/
|
||||
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK;
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
glitz_int_drawable_format_t format;
|
||||
int i, num_pixel_formats;
|
||||
int question, answer;
|
||||
glitz_wgl_static_proc_address_list_t *wgl = &screen_info->wgl;
|
||||
|
||||
for (i = 1; i <= num_pixel_formats; i++) {
|
||||
format.id = 0;
|
||||
|
||||
question = WGL_SUPPORT_OPENGL_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer) ||
|
||||
!answer)
|
||||
continue;
|
||||
|
||||
question = WGL_PIXEL_TYPE_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer) ||
|
||||
answer != WGL_TYPE_RGBA_ARB)
|
||||
continue;
|
||||
|
||||
/* Stereo is not supported yet */
|
||||
question = WGL_STEREO_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer) ||
|
||||
answer != 0)
|
||||
continue;
|
||||
|
||||
question = WGL_DRAW_TO_WINDOW_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.types.window = (answer) ? 1 : 0;
|
||||
|
||||
question = WGL_DRAW_TO_PBUFFER_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.types.pbuffer = (answer) ? 1 : 0;
|
||||
|
||||
if (!(format.types.window || format.types.pbuffer))
|
||||
continue;
|
||||
|
||||
question = WGL_RED_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.color.red_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_GREEN_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.color.green_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_BLUE_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.color.blue_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_ALPHA_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.color.alpha_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_DEPTH_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.depth_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_STENCIL_BITS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.stencil_size = (unsigned short) answer;
|
||||
|
||||
question = WGL_DOUBLE_BUFFER_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.doublebuffer = (answer) ? 1: 0;
|
||||
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
|
||||
question = WGL_SAMPLE_BUFFERS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
if (answer) {
|
||||
question = WGL_SAMPLES_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
|
||||
&question, &answer))
|
||||
continue;
|
||||
format.samples = (unsigned short) answer;
|
||||
} else {
|
||||
format.samples = 1;
|
||||
}
|
||||
} else {
|
||||
format.samples = 1;
|
||||
question = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, 0, 0, 1,
|
||||
&question, &num_pixel_formats)) {
|
||||
/* wglGetPixelFormatAttribivARB didn't work, fall back to
|
||||
* DescribePixelFormat.
|
||||
*/
|
||||
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK;
|
||||
return GLITZ_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
_glitz_add_format (screen_info, &format, i);
|
||||
}
|
||||
|
||||
return GLITZ_STATUS_SUCCESS;
|
||||
for (i = 1; i <= num_pixel_formats; i++) {
|
||||
format.d.id = 0;
|
||||
format.types = 0;
|
||||
format.d.color.fourcc = GLITZ_FOURCC_RGB;
|
||||
|
||||
#define ASK_QUESTION(q,a) (question=(q),wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1, &question,(a)))
|
||||
|
||||
if (!ASK_QUESTION(WGL_SUPPORT_OPENGL_ARB, &answer)
|
||||
|| !answer)
|
||||
continue;
|
||||
|
||||
if (!ASK_QUESTION(WGL_PIXEL_TYPE_ARB, &answer)
|
||||
|| answer != WGL_TYPE_RGBA_ARB)
|
||||
continue;
|
||||
|
||||
if (!ASK_QUESTION(WGL_ACCELERATION_ARB, &answer))
|
||||
continue;
|
||||
if (answer == WGL_NO_ACCELERATION_ARB)
|
||||
format.caveat = 2;
|
||||
else if (answer == WGL_GENERIC_ACCELERATION_ARB)
|
||||
format.caveat = 1;
|
||||
else
|
||||
format.caveat = 0;
|
||||
|
||||
/* Stereo is not supported yet */
|
||||
if (!ASK_QUESTION(WGL_STEREO_ARB, &answer)
|
||||
|| answer != 0)
|
||||
continue;
|
||||
|
||||
if (!ASK_QUESTION(WGL_DRAW_TO_WINDOW_ARB, &answer))
|
||||
continue;
|
||||
format.types |= answer ? GLITZ_DRAWABLE_TYPE_WINDOW_MASK : 0;
|
||||
|
||||
if (!ASK_QUESTION(WGL_DRAW_TO_PBUFFER_ARB, &answer))
|
||||
continue;
|
||||
format.types |= answer ? GLITZ_DRAWABLE_TYPE_PBUFFER_MASK : 0;
|
||||
|
||||
if (!(format.types & (GLITZ_DRAWABLE_TYPE_WINDOW_MASK |
|
||||
GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)))
|
||||
continue;
|
||||
|
||||
if (!ASK_QUESTION(WGL_RED_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.color.red_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_GREEN_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.color.green_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_BLUE_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.color.blue_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_ALPHA_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.color.alpha_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_DEPTH_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.depth_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_STENCIL_BITS_ARB, &answer))
|
||||
continue;
|
||||
format.d.stencil_size = (unsigned short) answer;
|
||||
|
||||
if (!ASK_QUESTION(WGL_DOUBLE_BUFFER_ARB, &answer))
|
||||
continue;
|
||||
format.d.doublebuffer = (answer) ? 1: 0;
|
||||
|
||||
format.d.samples = 1;
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
|
||||
if (!ASK_QUESTION(WGL_SAMPLE_BUFFERS_ARB, &answer))
|
||||
continue;
|
||||
|
||||
if (answer) {
|
||||
if (!ASK_QUESTION(WGL_SAMPLES_ARB, &answer))
|
||||
continue;
|
||||
format.d.samples = (unsigned short) answer;
|
||||
}
|
||||
}
|
||||
|
||||
_glitz_add_format (screen_info, &format, i);
|
||||
}
|
||||
|
||||
return GLITZ_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED;
|
||||
int *new_ids, i;
|
||||
glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED;
|
||||
int *new_ids, i;
|
||||
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK)
|
||||
status = _glitz_wgl_query_formats_using_pixel_format (screen_info);
|
||||
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK)
|
||||
status = _glitz_wgl_query_formats_using_pixel_format (screen_info);
|
||||
|
||||
if (status)
|
||||
_glitz_wgl_query_formats (screen_info);
|
||||
if (status)
|
||||
_glitz_wgl_query_formats (screen_info);
|
||||
|
||||
if (!screen_info->n_formats)
|
||||
return;
|
||||
if (!screen_info->n_formats)
|
||||
return;
|
||||
|
||||
qsort (screen_info->formats, screen_info->n_formats,
|
||||
sizeof (glitz_drawable_format_t), _glitz_wgl_format_compare);
|
||||
qsort (screen_info->formats, screen_info->n_formats,
|
||||
sizeof (glitz_int_drawable_format_t), _glitz_wgl_format_compare);
|
||||
|
||||
new_ids = malloc (sizeof (*new_ids) * screen_info->n_formats);
|
||||
new_ids = malloc (sizeof (*new_ids) * screen_info->n_formats);
|
||||
|
||||
for (i = 0; i < screen_info->n_formats; i++) {
|
||||
new_ids[i] = screen_info->format_ids[screen_info->formats[i].id];
|
||||
screen_info->formats[i].id = i;
|
||||
}
|
||||
|
||||
free (screen_info->format_ids);
|
||||
screen_info->format_ids = new_ids;
|
||||
for (i = 0; i < screen_info->n_formats; i++) {
|
||||
new_ids[i] = screen_info->format_ids[screen_info->formats[i].d.id];
|
||||
screen_info->formats[i].d.id = i;
|
||||
}
|
||||
|
||||
free (screen_info->format_ids);
|
||||
screen_info->format_ids = new_ids;
|
||||
}
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_wgl_find_drawable_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
glitz_wgl_find_window_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
{
|
||||
glitz_wgl_screen_info_t *screen_info =
|
||||
glitz_wgl_screen_info_get ();
|
||||
glitz_int_drawable_format_t itempl;
|
||||
glitz_wgl_screen_info_t *screen_info =
|
||||
glitz_wgl_screen_info_get ();
|
||||
|
||||
return glitz_drawable_format_find (screen_info->formats,
|
||||
screen_info->n_formats,
|
||||
mask, templ, count);
|
||||
glitz_drawable_format_copy (templ, &itempl.d, mask);
|
||||
|
||||
itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
|
||||
mask |= GLITZ_INT_FORMAT_WINDOW_MASK;
|
||||
|
||||
return glitz_drawable_format_find (screen_info->formats,
|
||||
screen_info->n_formats,
|
||||
mask, &itempl, count);
|
||||
}
|
||||
|
||||
glitz_drawable_format_t *
|
||||
glitz_wgl_find_pbuffer_format (unsigned long mask,
|
||||
const glitz_drawable_format_t *templ,
|
||||
int count)
|
||||
{
|
||||
glitz_int_drawable_format_t itempl;
|
||||
glitz_wgl_screen_info_t *screen_info =
|
||||
glitz_wgl_screen_info_get ();
|
||||
|
||||
glitz_drawable_format_copy (templ, &itempl.d, mask);
|
||||
|
||||
itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
|
||||
mask |= GLITZ_INT_FORMAT_PBUFFER_MASK;
|
||||
|
||||
return glitz_drawable_format_find (screen_info->formats,
|
||||
screen_info->n_formats,
|
||||
mask, &itempl, count);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -44,164 +44,178 @@
|
|||
void
|
||||
glitz_wgl_print_win32_error_string (int error_code)
|
||||
{
|
||||
char *msg = NULL;
|
||||
char *msg = NULL;
|
||||
|
||||
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, error_code, 0,
|
||||
(LPTSTR) &msg, 0, NULL);
|
||||
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, error_code, 0,
|
||||
(LPTSTR) &msg, 0, NULL);
|
||||
|
||||
if (msg != NULL)
|
||||
fprintf (stderr, "%s", msg);
|
||||
else
|
||||
fprintf (stderr, "Unknown error code %d", error_code);
|
||||
if (msg != NULL)
|
||||
fprintf (stderr, "%s", msg);
|
||||
else
|
||||
fprintf (stderr, "Unknown error code %d", error_code);
|
||||
|
||||
LocalFree (msg);
|
||||
LocalFree (msg);
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_win32_api_failed (const char *api)
|
||||
{
|
||||
fprintf (stderr, "%s failed: ", api);
|
||||
glitz_wgl_print_win32_error_string (GetLastError ());
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "%s failed: ", api);
|
||||
glitz_wgl_print_win32_error_string (GetLastError ());
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
glitz_gl_proc_address_list_t _glitz_wgl_gl_proc_address = {
|
||||
|
||||
/* core */
|
||||
(glitz_gl_enable_t) glEnable,
|
||||
(glitz_gl_disable_t) glDisable,
|
||||
(glitz_gl_get_error_t) glGetError,
|
||||
(glitz_gl_get_string_t) glGetString,
|
||||
(glitz_gl_enable_client_state_t) glEnableClientState,
|
||||
(glitz_gl_disable_client_state_t) glDisableClientState,
|
||||
(glitz_gl_vertex_pointer_t) glVertexPointer,
|
||||
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
|
||||
(glitz_gl_draw_arrays_t) glDrawArrays,
|
||||
(glitz_gl_tex_env_f_t) glTexEnvf,
|
||||
(glitz_gl_tex_env_fv_t) glTexEnvfv,
|
||||
(glitz_gl_tex_gen_i_t) glTexGeni,
|
||||
(glitz_gl_tex_gen_fv_t) glTexGenfv,
|
||||
(glitz_gl_color_4us_t) glColor4us,
|
||||
(glitz_gl_color_4f_t) glColor4f,
|
||||
(glitz_gl_scissor_t) glScissor,
|
||||
(glitz_gl_blend_func_t) glBlendFunc,
|
||||
(glitz_gl_clear_t) glClear,
|
||||
(glitz_gl_clear_color_t) glClearColor,
|
||||
(glitz_gl_clear_stencil_t) glClearStencil,
|
||||
(glitz_gl_stencil_func_t) glStencilFunc,
|
||||
(glitz_gl_stencil_op_t) glStencilOp,
|
||||
(glitz_gl_push_attrib_t) glPushAttrib,
|
||||
(glitz_gl_pop_attrib_t) glPopAttrib,
|
||||
(glitz_gl_matrix_mode_t) glMatrixMode,
|
||||
(glitz_gl_push_matrix_t) glPushMatrix,
|
||||
(glitz_gl_pop_matrix_t) glPopMatrix,
|
||||
(glitz_gl_load_identity_t) glLoadIdentity,
|
||||
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
|
||||
(glitz_gl_depth_range_t) glDepthRange,
|
||||
(glitz_gl_viewport_t) glViewport,
|
||||
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
|
||||
(glitz_gl_bitmap_t) glBitmap,
|
||||
(glitz_gl_read_buffer_t) glReadBuffer,
|
||||
(glitz_gl_draw_buffer_t) glDrawBuffer,
|
||||
(glitz_gl_copy_pixels_t) glCopyPixels,
|
||||
(glitz_gl_flush_t) glFlush,
|
||||
(glitz_gl_finish_t) glFinish,
|
||||
(glitz_gl_pixel_store_i_t) glPixelStorei,
|
||||
(glitz_gl_ortho_t) glOrtho,
|
||||
(glitz_gl_scale_f_t) glScalef,
|
||||
(glitz_gl_translate_f_t) glTranslatef,
|
||||
(glitz_gl_hint_t) glHint,
|
||||
(glitz_gl_depth_mask_t) glDepthMask,
|
||||
(glitz_gl_polygon_mode_t) glPolygonMode,
|
||||
(glitz_gl_shade_model_t) glShadeModel,
|
||||
(glitz_gl_color_mask_t) glColorMask,
|
||||
(glitz_gl_read_pixels_t) glReadPixels,
|
||||
(glitz_gl_get_tex_image_t) glGetTexImage,
|
||||
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
|
||||
(glitz_gl_gen_textures_t) glGenTextures,
|
||||
(glitz_gl_delete_textures_t) glDeleteTextures,
|
||||
(glitz_gl_bind_texture_t) glBindTexture,
|
||||
(glitz_gl_tex_image_2d_t) glTexImage2D,
|
||||
(glitz_gl_tex_parameter_i_t) glTexParameteri,
|
||||
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
|
||||
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
|
||||
(glitz_gl_get_integer_v_t) glGetIntegerv,
|
||||
/* core */
|
||||
(glitz_gl_enable_t) glEnable,
|
||||
(glitz_gl_disable_t) glDisable,
|
||||
(glitz_gl_get_error_t) glGetError,
|
||||
(glitz_gl_get_string_t) glGetString,
|
||||
(glitz_gl_enable_client_state_t) glEnableClientState,
|
||||
(glitz_gl_disable_client_state_t) glDisableClientState,
|
||||
(glitz_gl_vertex_pointer_t) glVertexPointer,
|
||||
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
|
||||
(glitz_gl_draw_arrays_t) glDrawArrays,
|
||||
(glitz_gl_tex_env_f_t) glTexEnvf,
|
||||
(glitz_gl_tex_env_fv_t) glTexEnvfv,
|
||||
(glitz_gl_tex_gen_i_t) glTexGeni,
|
||||
(glitz_gl_tex_gen_fv_t) glTexGenfv,
|
||||
(glitz_gl_color_4us_t) glColor4us,
|
||||
(glitz_gl_color_4f_t) glColor4f,
|
||||
(glitz_gl_scissor_t) glScissor,
|
||||
(glitz_gl_blend_func_t) glBlendFunc,
|
||||
(glitz_gl_clear_t) glClear,
|
||||
(glitz_gl_clear_color_t) glClearColor,
|
||||
(glitz_gl_clear_stencil_t) glClearStencil,
|
||||
(glitz_gl_stencil_func_t) glStencilFunc,
|
||||
(glitz_gl_stencil_op_t) glStencilOp,
|
||||
(glitz_gl_push_attrib_t) glPushAttrib,
|
||||
(glitz_gl_pop_attrib_t) glPopAttrib,
|
||||
(glitz_gl_matrix_mode_t) glMatrixMode,
|
||||
(glitz_gl_push_matrix_t) glPushMatrix,
|
||||
(glitz_gl_pop_matrix_t) glPopMatrix,
|
||||
(glitz_gl_load_identity_t) glLoadIdentity,
|
||||
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
|
||||
(glitz_gl_depth_range_t) glDepthRange,
|
||||
(glitz_gl_viewport_t) glViewport,
|
||||
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
|
||||
(glitz_gl_bitmap_t) glBitmap,
|
||||
(glitz_gl_read_buffer_t) glReadBuffer,
|
||||
(glitz_gl_draw_buffer_t) glDrawBuffer,
|
||||
(glitz_gl_copy_pixels_t) glCopyPixels,
|
||||
(glitz_gl_flush_t) glFlush,
|
||||
(glitz_gl_finish_t) glFinish,
|
||||
(glitz_gl_pixel_store_i_t) glPixelStorei,
|
||||
(glitz_gl_ortho_t) glOrtho,
|
||||
(glitz_gl_scale_f_t) glScalef,
|
||||
(glitz_gl_translate_f_t) glTranslatef,
|
||||
(glitz_gl_hint_t) glHint,
|
||||
(glitz_gl_depth_mask_t) glDepthMask,
|
||||
(glitz_gl_polygon_mode_t) glPolygonMode,
|
||||
(glitz_gl_shade_model_t) glShadeModel,
|
||||
(glitz_gl_color_mask_t) glColorMask,
|
||||
(glitz_gl_read_pixels_t) glReadPixels,
|
||||
(glitz_gl_get_tex_image_t) glGetTexImage,
|
||||
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
|
||||
(glitz_gl_gen_textures_t) glGenTextures,
|
||||
(glitz_gl_delete_textures_t) glDeleteTextures,
|
||||
(glitz_gl_bind_texture_t) glBindTexture,
|
||||
(glitz_gl_tex_image_2d_t) glTexImage2D,
|
||||
(glitz_gl_tex_parameter_i_t) glTexParameteri,
|
||||
(glitz_gl_tex_parameter_fv_t) glTexParameterfv,
|
||||
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
|
||||
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
|
||||
(glitz_gl_get_integer_v_t) glGetIntegerv,
|
||||
|
||||
/* extensions */
|
||||
(glitz_gl_blend_color_t) 0,
|
||||
(glitz_gl_active_texture_t) 0,
|
||||
(glitz_gl_client_active_texture_t) 0,
|
||||
(glitz_gl_multi_draw_arrays_t) 0,
|
||||
(glitz_gl_gen_programs_t) 0,
|
||||
(glitz_gl_delete_programs_t) 0,
|
||||
(glitz_gl_program_string_t) 0,
|
||||
(glitz_gl_bind_program_t) 0,
|
||||
(glitz_gl_program_local_param_4fv_t) 0,
|
||||
(glitz_gl_get_program_iv_t) 0,
|
||||
(glitz_gl_gen_buffers_t) 0,
|
||||
(glitz_gl_delete_buffers_t) 0,
|
||||
(glitz_gl_bind_buffer_t) 0,
|
||||
(glitz_gl_buffer_data_t) 0,
|
||||
(glitz_gl_buffer_sub_data_t) 0,
|
||||
(glitz_gl_get_buffer_sub_data_t) 0,
|
||||
(glitz_gl_map_buffer_t) 0,
|
||||
(glitz_gl_unmap_buffer_t) 0
|
||||
/* extensions */
|
||||
(glitz_gl_blend_color_t) 0,
|
||||
(glitz_gl_active_texture_t) 0,
|
||||
(glitz_gl_client_active_texture_t) 0,
|
||||
(glitz_gl_multi_draw_arrays_t) 0,
|
||||
(glitz_gl_gen_programs_t) 0,
|
||||
(glitz_gl_delete_programs_t) 0,
|
||||
(glitz_gl_program_string_t) 0,
|
||||
(glitz_gl_bind_program_t) 0,
|
||||
(glitz_gl_program_local_param_4fv_t) 0,
|
||||
(glitz_gl_get_program_iv_t) 0,
|
||||
(glitz_gl_gen_buffers_t) 0,
|
||||
(glitz_gl_delete_buffers_t) 0,
|
||||
(glitz_gl_bind_buffer_t) 0,
|
||||
(glitz_gl_buffer_data_t) 0,
|
||||
(glitz_gl_buffer_sub_data_t) 0,
|
||||
(glitz_gl_get_buffer_sub_data_t) 0,
|
||||
(glitz_gl_map_buffer_t) 0,
|
||||
(glitz_gl_unmap_buffer_t) 0,
|
||||
(glitz_gl_gen_framebuffers_t) 0,
|
||||
(glitz_gl_delete_framebuffers_t) 0,
|
||||
(glitz_gl_bind_framebuffer_t) 0,
|
||||
(glitz_gl_framebuffer_renderbuffer_t) 0,
|
||||
(glitz_gl_framebuffer_texture_2d_t) 0,
|
||||
(glitz_gl_check_framebuffer_status_t) 0,
|
||||
(glitz_gl_gen_renderbuffers_t) 0,
|
||||
(glitz_gl_delete_renderbuffers_t) 0,
|
||||
(glitz_gl_bind_renderbuffer_t) 0,
|
||||
(glitz_gl_renderbuffer_storage_t) 0,
|
||||
(glitz_gl_get_renderbuffer_parameter_iv_t) 0
|
||||
};
|
||||
|
||||
glitz_function_pointer_t
|
||||
glitz_wgl_get_proc_address (const char *name,
|
||||
void *closure)
|
||||
{
|
||||
glitz_wgl_screen_info_t *screen_info = (glitz_wgl_screen_info_t *) closure;
|
||||
glitz_wgl_thread_info_t *info = screen_info->thread_info;
|
||||
glitz_function_pointer_t address = (glitz_function_pointer_t) wglGetProcAddress (name);
|
||||
glitz_wgl_screen_info_t *screen_info = (glitz_wgl_screen_info_t *) closure;
|
||||
glitz_wgl_thread_info_t *info = screen_info->thread_info;
|
||||
glitz_function_pointer_t address = (glitz_function_pointer_t)
|
||||
wglGetProcAddress (name);
|
||||
|
||||
if (!address && info->gl_library) {
|
||||
/* Not sure whether this has any use at all... */
|
||||
if (!address && info->gl_library) {
|
||||
/* Not sure whether this has any use at all... */
|
||||
|
||||
if (!info->dlhand)
|
||||
info->dlhand = LoadLibrary (info->gl_library);
|
||||
if (!info->dlhand)
|
||||
info->dlhand = LoadLibrary (info->gl_library);
|
||||
|
||||
if (info->dlhand) {
|
||||
address = (glitz_function_pointer_t) GetProcAddress (info->dlhand, name);
|
||||
if (info->dlhand) {
|
||||
address = (glitz_function_pointer_t)
|
||||
GetProcAddress (info->dlhand, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return address;
|
||||
return address;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_proc_address_lookup (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
screen_info->wgl.get_pixel_format_attrib_iv =
|
||||
(glitz_wgl_get_pixel_format_attrib_iv_t)
|
||||
glitz_wgl_get_proc_address ("wglGetPixelFormatAttribivARB", screen_info);
|
||||
screen_info->wgl.choose_pixel_format = (glitz_wgl_choose_pixel_format_t)
|
||||
glitz_wgl_get_proc_address ("wglChoosePixelFormatARB", screen_info);
|
||||
screen_info->wgl.get_pixel_format_attrib_iv =
|
||||
(glitz_wgl_get_pixel_format_attrib_iv_t)
|
||||
glitz_wgl_get_proc_address ("wglGetPixelFormatAttribivARB", screen_info);
|
||||
screen_info->wgl.choose_pixel_format = (glitz_wgl_choose_pixel_format_t)
|
||||
glitz_wgl_get_proc_address ("wglChoosePixelFormatARB", screen_info);
|
||||
|
||||
screen_info->wgl.create_pbuffer = (glitz_wgl_create_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglCreatePbufferARB", screen_info);
|
||||
screen_info->wgl.get_pbuffer_dc = (glitz_wgl_get_pbuffer_dc_t)
|
||||
glitz_wgl_get_proc_address ("wglGetPbufferDCARB", screen_info);
|
||||
screen_info->wgl.release_pbuffer_dc = (glitz_wgl_release_pbuffer_dc_t)
|
||||
glitz_wgl_get_proc_address ("wglReleasePbufferDCARB", screen_info);
|
||||
screen_info->wgl.destroy_pbuffer = (glitz_wgl_destroy_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglDestroyPbufferARB", screen_info);
|
||||
screen_info->wgl.query_pbuffer = (glitz_wgl_query_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglQueryPbufferARB", screen_info);
|
||||
screen_info->wgl.create_pbuffer = (glitz_wgl_create_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglCreatePbufferARB", screen_info);
|
||||
screen_info->wgl.get_pbuffer_dc = (glitz_wgl_get_pbuffer_dc_t)
|
||||
glitz_wgl_get_proc_address ("wglGetPbufferDCARB", screen_info);
|
||||
screen_info->wgl.release_pbuffer_dc = (glitz_wgl_release_pbuffer_dc_t)
|
||||
glitz_wgl_get_proc_address ("wglReleasePbufferDCARB", screen_info);
|
||||
screen_info->wgl.destroy_pbuffer = (glitz_wgl_destroy_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglDestroyPbufferARB", screen_info);
|
||||
screen_info->wgl.query_pbuffer = (glitz_wgl_query_pbuffer_t)
|
||||
glitz_wgl_get_proc_address ("wglQueryPbufferARB", screen_info);
|
||||
|
||||
screen_info->wgl.make_context_current = (glitz_wgl_make_context_current_t)
|
||||
glitz_wgl_get_proc_address ("wglMakeContextCurrentARB", screen_info);
|
||||
screen_info->wgl.make_context_current = (glitz_wgl_make_context_current_t)
|
||||
glitz_wgl_get_proc_address ("wglMakeContextCurrentARB", screen_info);
|
||||
|
||||
if ((!screen_info->wgl.create_pbuffer) ||
|
||||
(!screen_info->wgl.destroy_pbuffer) ||
|
||||
(!screen_info->wgl.query_pbuffer))
|
||||
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PBUFFER_MASK;
|
||||
|
||||
if ((!screen_info->wgl.create_pbuffer) ||
|
||||
(!screen_info->wgl.destroy_pbuffer) ||
|
||||
(!screen_info->wgl.query_pbuffer))
|
||||
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PBUFFER_MASK;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -210,27 +224,27 @@ _glitz_wgl_screen_destroy (glitz_wgl_screen_info_t *screen_info);
|
|||
static void
|
||||
_glitz_wgl_thread_info_init (glitz_wgl_thread_info_t *thread_info)
|
||||
{
|
||||
thread_info->screen = NULL;
|
||||
thread_info->gl_library = NULL;
|
||||
thread_info->dlhand = NULL;
|
||||
thread_info->screen = NULL;
|
||||
thread_info->gl_library = NULL;
|
||||
thread_info->dlhand = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_thread_info_fini (glitz_wgl_thread_info_t *thread_info)
|
||||
{
|
||||
_glitz_wgl_screen_destroy (thread_info->screen);
|
||||
_glitz_wgl_screen_destroy (thread_info->screen);
|
||||
|
||||
thread_info->screen = NULL;
|
||||
thread_info->screen = NULL;
|
||||
|
||||
if (thread_info->gl_library) {
|
||||
free (thread_info->gl_library);
|
||||
thread_info->gl_library = NULL;
|
||||
}
|
||||
if (thread_info->gl_library) {
|
||||
free (thread_info->gl_library);
|
||||
thread_info->gl_library = NULL;
|
||||
}
|
||||
|
||||
if (thread_info->dlhand) {
|
||||
FreeLibrary (thread_info->dlhand);
|
||||
thread_info->dlhand = NULL;
|
||||
}
|
||||
if (thread_info->dlhand) {
|
||||
FreeLibrary (thread_info->dlhand);
|
||||
thread_info->dlhand = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int tsd_initialized = 0;
|
||||
|
@ -239,261 +253,261 @@ static DWORD info_tsd;
|
|||
static void
|
||||
_glitz_wgl_thread_info_destroy (glitz_wgl_thread_info_t *thread_info)
|
||||
{
|
||||
TlsSetValue (info_tsd, NULL);
|
||||
|
||||
if (thread_info) {
|
||||
_glitz_wgl_thread_info_fini (thread_info);
|
||||
free (thread_info);
|
||||
}
|
||||
TlsSetValue (info_tsd, NULL);
|
||||
|
||||
if (thread_info) {
|
||||
_glitz_wgl_thread_info_fini (thread_info);
|
||||
free (thread_info);
|
||||
}
|
||||
}
|
||||
|
||||
static glitz_wgl_thread_info_t *
|
||||
_glitz_wgl_thread_info_get_inner (void)
|
||||
{
|
||||
glitz_wgl_thread_info_t *thread_info;
|
||||
void *p;
|
||||
|
||||
if (!tsd_initialized) {
|
||||
info_tsd = TlsAlloc ();
|
||||
tsd_initialized = 1;
|
||||
}
|
||||
glitz_wgl_thread_info_t *thread_info;
|
||||
void *p;
|
||||
|
||||
p = TlsGetValue (info_tsd);
|
||||
|
||||
if (p == NULL) {
|
||||
thread_info = malloc (sizeof (glitz_wgl_thread_info_t));
|
||||
_glitz_wgl_thread_info_init (thread_info);
|
||||
|
||||
TlsSetValue (info_tsd, thread_info);
|
||||
} else
|
||||
thread_info = (glitz_wgl_thread_info_t *) p;
|
||||
|
||||
return thread_info;
|
||||
if (!tsd_initialized) {
|
||||
info_tsd = TlsAlloc ();
|
||||
tsd_initialized = 1;
|
||||
}
|
||||
|
||||
p = TlsGetValue (info_tsd);
|
||||
|
||||
if (p == NULL) {
|
||||
thread_info = malloc (sizeof (glitz_wgl_thread_info_t));
|
||||
_glitz_wgl_thread_info_init (thread_info);
|
||||
|
||||
TlsSetValue (info_tsd, thread_info);
|
||||
} else
|
||||
thread_info = (glitz_wgl_thread_info_t *) p;
|
||||
|
||||
return thread_info;
|
||||
}
|
||||
|
||||
static glitz_wgl_thread_info_t *
|
||||
_glitz_wgl_thread_info_get (const char *gl_library)
|
||||
{
|
||||
glitz_wgl_thread_info_t *thread_info = _glitz_wgl_thread_info_get_inner ();
|
||||
glitz_wgl_thread_info_t *thread_info = _glitz_wgl_thread_info_get_inner ();
|
||||
|
||||
if (gl_library) {
|
||||
int len = strlen (gl_library);
|
||||
|
||||
if (thread_info->gl_library) {
|
||||
free (thread_info->gl_library);
|
||||
thread_info->gl_library = NULL;
|
||||
}
|
||||
|
||||
thread_info->gl_library = malloc (len + 1);
|
||||
if (thread_info->gl_library) {
|
||||
memcpy (thread_info->gl_library, gl_library, len);
|
||||
thread_info->gl_library[len] = '\0';
|
||||
}
|
||||
}
|
||||
if (gl_library) {
|
||||
int len = strlen (gl_library);
|
||||
|
||||
return thread_info;
|
||||
if (thread_info->gl_library) {
|
||||
free (thread_info->gl_library);
|
||||
thread_info->gl_library = NULL;
|
||||
}
|
||||
|
||||
thread_info->gl_library = malloc (len + 1);
|
||||
if (thread_info->gl_library) {
|
||||
memcpy (thread_info->gl_library, gl_library, len);
|
||||
thread_info->gl_library[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return thread_info;
|
||||
}
|
||||
|
||||
int
|
||||
glitz_wgl_thread_starter (const glitz_wgl_thread_starter_arg_t *arg)
|
||||
{
|
||||
glitz_wgl_thread_info_t *thread_info;
|
||||
int retval;
|
||||
glitz_wgl_thread_info_t *thread_info;
|
||||
int retval;
|
||||
|
||||
retval = (*arg->user_thread_function) (arg->user_thread_function_arg);
|
||||
retval = (*arg->user_thread_function) (arg->user_thread_function_arg);
|
||||
|
||||
if (tsd_initialized) {
|
||||
thread_info = (glitz_wgl_thread_info_t *) TlsGetValue (info_tsd);
|
||||
_glitz_wgl_thread_info_fini (thread_info);
|
||||
free (thread_info);
|
||||
}
|
||||
if (tsd_initialized) {
|
||||
thread_info = (glitz_wgl_thread_info_t *) TlsGetValue (info_tsd);
|
||||
_glitz_wgl_thread_info_fini (thread_info);
|
||||
free (thread_info);
|
||||
}
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_create_root_context (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
WNDCLASSEX wcl;
|
||||
ATOM klass;
|
||||
WNDCLASSEX wcl;
|
||||
ATOM klass;
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof (PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
|
||||
PFD_TYPE_RGBA,
|
||||
32,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
static PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof (PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
|
||||
PFD_TYPE_RGBA,
|
||||
32,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
int pixel_format;
|
||||
int pixel_format;
|
||||
|
||||
wcl.cbSize = sizeof (wcl);
|
||||
wcl.style = 0;
|
||||
wcl.lpfnWndProc = DefWindowProc;
|
||||
wcl.cbClsExtra = 0;
|
||||
wcl.cbWndExtra = 0;
|
||||
wcl.hInstance = GetModuleHandle (NULL);
|
||||
wcl.hIcon = NULL;
|
||||
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
wcl.hbrBackground = NULL;
|
||||
wcl.lpszMenuName = NULL;
|
||||
wcl.lpszClassName = "glitz-wgl-root-window-class";
|
||||
wcl.hIconSm = NULL;
|
||||
wcl.cbSize = sizeof (wcl);
|
||||
wcl.style = 0;
|
||||
wcl.lpfnWndProc = DefWindowProc;
|
||||
wcl.cbClsExtra = 0;
|
||||
wcl.cbWndExtra = 0;
|
||||
wcl.hInstance = GetModuleHandle (NULL);
|
||||
wcl.hIcon = NULL;
|
||||
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
wcl.hbrBackground = NULL;
|
||||
wcl.lpszMenuName = NULL;
|
||||
wcl.lpszClassName = "glitz-wgl-root-window-class";
|
||||
wcl.hIconSm = NULL;
|
||||
|
||||
klass = RegisterClassEx (&wcl);
|
||||
klass = RegisterClassEx (&wcl);
|
||||
|
||||
if (!klass) {
|
||||
exit (1);
|
||||
}
|
||||
if (!klass) {
|
||||
exit (1);
|
||||
}
|
||||
|
||||
screen_info->root_window =
|
||||
CreateWindowEx (0, (LPCTSTR) (DWORD) klass, "glitz-wgl-root-window",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
100, 100,
|
||||
GetDesktopWindow (),
|
||||
NULL, GetModuleHandle (NULL), NULL);
|
||||
screen_info->root_window =
|
||||
CreateWindowEx (0, (LPCTSTR) (DWORD) klass, "glitz-wgl-root-window",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
100, 100,
|
||||
GetDesktopWindow (),
|
||||
NULL, GetModuleHandle (NULL), NULL);
|
||||
|
||||
screen_info->root_dc = GetDC (screen_info->root_window);
|
||||
screen_info->root_dc = GetDC (screen_info->root_window);
|
||||
|
||||
pixel_format = ChoosePixelFormat (screen_info->root_dc, &pfd);
|
||||
pixel_format = ChoosePixelFormat (screen_info->root_dc, &pfd);
|
||||
|
||||
if (pixel_format != 0) {
|
||||
SetPixelFormat (screen_info->root_dc, pixel_format, &pfd);
|
||||
if (pixel_format != 0) {
|
||||
SetPixelFormat (screen_info->root_dc, pixel_format, &pfd);
|
||||
|
||||
screen_info->root_context = wglCreateContext (screen_info->root_dc);
|
||||
screen_info->root_context = wglCreateContext (screen_info->root_dc);
|
||||
|
||||
wglMakeCurrent (screen_info->root_dc, screen_info->root_context);
|
||||
} else {
|
||||
screen_info->root_context = NULL;
|
||||
}
|
||||
wglMakeCurrent (screen_info->root_dc, screen_info->root_context);
|
||||
} else {
|
||||
screen_info->root_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
glitz_wgl_screen_info_t *
|
||||
glitz_wgl_screen_info_get (void)
|
||||
{
|
||||
static glitz_wgl_screen_info_t *screen_info = NULL;
|
||||
const char *gl_version;
|
||||
static glitz_wgl_screen_info_t *screen_info = NULL;
|
||||
const char *gl_version;
|
||||
|
||||
if (screen_info != NULL)
|
||||
return screen_info;
|
||||
if (screen_info != NULL)
|
||||
return screen_info;
|
||||
|
||||
screen_info = malloc (sizeof (glitz_wgl_screen_info_t));
|
||||
screen_info = malloc (sizeof (glitz_wgl_screen_info_t));
|
||||
|
||||
screen_info->drawables = 0;
|
||||
screen_info->formats = NULL;
|
||||
screen_info->format_ids = NULL;
|
||||
screen_info->n_formats = 0;
|
||||
screen_info->drawables = 0;
|
||||
screen_info->formats = NULL;
|
||||
screen_info->format_ids = NULL;
|
||||
screen_info->n_formats = 0;
|
||||
|
||||
screen_info->contexts = NULL;
|
||||
screen_info->n_contexts = 0;
|
||||
screen_info->contexts = NULL;
|
||||
screen_info->n_contexts = 0;
|
||||
|
||||
memset (&screen_info->wgl, 0, sizeof (glitz_wgl_static_proc_address_list_t));
|
||||
memset (&screen_info->wgl, 0, sizeof (glitz_wgl_static_proc_address_list_t));
|
||||
|
||||
glitz_program_map_init (&screen_info->program_map);
|
||||
glitz_program_map_init (&screen_info->program_map);
|
||||
|
||||
_glitz_wgl_create_root_context (screen_info);
|
||||
_glitz_wgl_create_root_context (screen_info);
|
||||
|
||||
gl_version = glGetString (GL_VERSION);
|
||||
gl_version = glGetString (GL_VERSION);
|
||||
|
||||
screen_info->wgl_version = 1;
|
||||
screen_info->wgl_version = 1;
|
||||
|
||||
/* Can't use atof(), as GL_VERSION might always use a decimal period,
|
||||
* but atof() looks for the locale-specific decimal separator.
|
||||
*/
|
||||
if (gl_version != NULL && gl_version[0]) {
|
||||
int whole_part;
|
||||
int n;
|
||||
if (sscanf (gl_version, "%d%n", &whole_part, &n) == 1 &&
|
||||
(gl_version[n] == '.' ||
|
||||
gl_version[n] == ',')) {
|
||||
double fraction = 0.1;
|
||||
/* Can't use atof(), as GL_VERSION might always use a decimal period,
|
||||
* but atof() looks for the locale-specific decimal separator.
|
||||
*/
|
||||
if (gl_version != NULL && gl_version[0]) {
|
||||
int whole_part;
|
||||
int n;
|
||||
if (sscanf (gl_version, "%d%n", &whole_part, &n) == 1 &&
|
||||
(gl_version[n] == '.' ||
|
||||
gl_version[n] == ',')) {
|
||||
double fraction = 0.1;
|
||||
|
||||
screen_info->wgl_version = whole_part;
|
||||
while (isdigit (gl_version[n+1])) {
|
||||
screen_info->wgl_version += (gl_version[n+1] - '0') * fraction;
|
||||
fraction /= 10;
|
||||
n++;
|
||||
}
|
||||
screen_info->wgl_version = whole_part;
|
||||
while (isdigit (gl_version[n+1])) {
|
||||
screen_info->wgl_version += (gl_version[n+1] - '0') * fraction;
|
||||
fraction /= 10;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen_info->wgl_feature_mask = 0;
|
||||
screen_info->wgl_feature_mask = 0;
|
||||
|
||||
screen_info->thread_info = _glitz_wgl_thread_info_get_inner ();
|
||||
screen_info->thread_info->screen = screen_info;
|
||||
_glitz_wgl_thread_info_get (NULL);
|
||||
screen_info->thread_info = _glitz_wgl_thread_info_get_inner ();
|
||||
screen_info->thread_info->screen = screen_info;
|
||||
_glitz_wgl_thread_info_get (NULL);
|
||||
|
||||
glitz_wgl_query_extensions (screen_info, screen_info->wgl_version);
|
||||
_glitz_wgl_proc_address_lookup (screen_info);
|
||||
glitz_wgl_query_formats (screen_info);
|
||||
|
||||
screen_info->context_stack_size = 1;
|
||||
screen_info->context_stack->drawable = NULL;
|
||||
screen_info->context_stack->surface = NULL;
|
||||
screen_info->context_stack->constraint = GLITZ_NONE;
|
||||
|
||||
return screen_info;
|
||||
glitz_wgl_query_extensions (screen_info, screen_info->wgl_version);
|
||||
_glitz_wgl_proc_address_lookup (screen_info);
|
||||
glitz_wgl_query_formats (screen_info);
|
||||
|
||||
screen_info->context_stack_size = 1;
|
||||
screen_info->context_stack->drawable = NULL;
|
||||
screen_info->context_stack->surface = NULL;
|
||||
screen_info->context_stack->constraint = GLITZ_NONE;
|
||||
|
||||
return screen_info;
|
||||
}
|
||||
|
||||
static void
|
||||
_glitz_wgl_screen_destroy (glitz_wgl_screen_info_t *screen_info)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (screen_info->root_context) {
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
if (screen_info->root_context) {
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < screen_info->n_contexts; i++)
|
||||
glitz_wgl_context_destroy (screen_info, screen_info->contexts[i]);
|
||||
for (i = 0; i < screen_info->n_contexts; i++)
|
||||
glitz_wgl_context_destroy (screen_info, screen_info->contexts[i]);
|
||||
|
||||
if (screen_info->contexts)
|
||||
free (screen_info->contexts);
|
||||
|
||||
if (screen_info->formats)
|
||||
free (screen_info->formats);
|
||||
if (screen_info->contexts)
|
||||
free (screen_info->contexts);
|
||||
|
||||
if (screen_info->format_ids)
|
||||
free (screen_info->format_ids);
|
||||
|
||||
if (screen_info->root_context) {
|
||||
wglDeleteContext (screen_info->root_context);
|
||||
}
|
||||
|
||||
if (screen_info->root_dc) {
|
||||
DeleteDC (screen_info->root_dc);
|
||||
}
|
||||
if (screen_info->formats)
|
||||
free (screen_info->formats);
|
||||
|
||||
if (screen_info->root_window) {
|
||||
DestroyWindow (screen_info->root_window);
|
||||
}
|
||||
if (screen_info->format_ids)
|
||||
free (screen_info->format_ids);
|
||||
|
||||
free (screen_info);
|
||||
if (screen_info->root_context) {
|
||||
wglDeleteContext (screen_info->root_context);
|
||||
}
|
||||
|
||||
if (screen_info->root_dc) {
|
||||
DeleteDC (screen_info->root_dc);
|
||||
}
|
||||
|
||||
if (screen_info->root_window) {
|
||||
DestroyWindow (screen_info->root_window);
|
||||
}
|
||||
|
||||
free (screen_info);
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_init (const char *gl_library)
|
||||
{
|
||||
_glitz_wgl_thread_info_get (gl_library);
|
||||
_glitz_wgl_thread_info_get (gl_library);
|
||||
}
|
||||
|
||||
void
|
||||
glitz_wgl_fini (void)
|
||||
{
|
||||
glitz_wgl_thread_info_t *info = _glitz_wgl_thread_info_get (NULL);
|
||||
glitz_wgl_thread_info_t *info = _glitz_wgl_thread_info_get (NULL);
|
||||
|
||||
_glitz_wgl_thread_info_destroy (info);
|
||||
_glitz_wgl_thread_info_destroy (info);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -37,35 +37,35 @@
|
|||
HPBUFFERARB
|
||||
glitz_wgl_pbuffer_create (glitz_wgl_screen_info_t *screen_info,
|
||||
int pixel_format,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
HDC *dcp)
|
||||
{
|
||||
if (pixel_format) {
|
||||
HPBUFFERARB retval;
|
||||
int pbuffer_attr[3], i = 0;
|
||||
if (pixel_format) {
|
||||
HPBUFFERARB retval;
|
||||
int pbuffer_attr[3], i = 0;
|
||||
|
||||
pbuffer_attr[i++] = WGL_PBUFFER_LARGEST_ARB;
|
||||
pbuffer_attr[i++] = 0;
|
||||
pbuffer_attr[i++] = 0;
|
||||
pbuffer_attr[i++] = WGL_PBUFFER_LARGEST_ARB;
|
||||
pbuffer_attr[i++] = 0;
|
||||
pbuffer_attr[i++] = 0;
|
||||
|
||||
retval =
|
||||
screen_info->wgl.create_pbuffer (screen_info->root_dc, pixel_format,
|
||||
width, height, pbuffer_attr);
|
||||
if (retval != NULL) {
|
||||
*dcp = screen_info->wgl.get_pbuffer_dc (retval);
|
||||
return retval;
|
||||
retval =
|
||||
screen_info->wgl.create_pbuffer (screen_info->root_dc, pixel_format,
|
||||
width, height, pbuffer_attr);
|
||||
if (retval != NULL) {
|
||||
*dcp = screen_info->wgl.get_pbuffer_dc (retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dcp = NULL;
|
||||
return NULL;
|
||||
*dcp = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
glitz_wgl_pbuffer_destroy (glitz_wgl_screen_info_t *screen_info,
|
||||
HPBUFFERARB pbuffer,
|
||||
HPBUFFERARB pbuffer,
|
||||
HDC dc)
|
||||
{
|
||||
screen_info->wgl.release_pbuffer_dc (pbuffer, dc);
|
||||
screen_info->wgl.destroy_pbuffer (pbuffer);
|
||||
screen_info->wgl.release_pbuffer_dc (pbuffer, dc);
|
||||
screen_info->wgl.destroy_pbuffer (pbuffer);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 David Reveman
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
|
@ -12,11 +12,11 @@
|
|||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
*
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
|
@ -98,7 +98,7 @@ typedef struct _glitz_wgl_context_t {
|
|||
struct _glitz_wgl_screen_info_t {
|
||||
glitz_wgl_thread_info_t *thread_info;
|
||||
int drawables;
|
||||
glitz_drawable_format_t *formats;
|
||||
glitz_int_drawable_format_t *formats;
|
||||
int *format_ids;
|
||||
int n_formats;
|
||||
glitz_wgl_context_t **contexts;
|
||||
|
@ -143,34 +143,34 @@ glitz_wgl_get_proc_address (const char *name,
|
|||
extern glitz_wgl_context_t *__internal_linkage
|
||||
glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
|
||||
HDC dc,
|
||||
glitz_drawable_format_t *format);
|
||||
glitz_drawable_format_t *format);
|
||||
|
||||
extern void __internal_linkage
|
||||
glitz_wgl_context_destroy (glitz_wgl_screen_info_t *screen_info,
|
||||
glitz_wgl_context_t *context);
|
||||
glitz_wgl_context_t *context);
|
||||
|
||||
extern void __internal_linkage
|
||||
glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info);
|
||||
|
||||
extern HPBUFFERARB __internal_linkage
|
||||
glitz_wgl_pbuffer_create (glitz_wgl_screen_info_t *screen_info,
|
||||
int pixel_format,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
int pixel_format,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
HDC *dcp);
|
||||
|
||||
extern void __internal_linkage
|
||||
glitz_wgl_pbuffer_destroy (glitz_wgl_screen_info_t *screen_info,
|
||||
HPBUFFERARB pbuffer,
|
||||
HPBUFFERARB pbuffer,
|
||||
HDC dc);
|
||||
|
||||
extern glitz_drawable_t *__internal_linkage
|
||||
glitz_wgl_create_pbuffer (void *abstract_templ,
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
glitz_drawable_format_t *format,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
extern void __internal_linkage
|
||||
extern glitz_bool_t __internal_linkage
|
||||
glitz_wgl_push_current (void *abstract_drawable,
|
||||
glitz_surface_t *surface,
|
||||
glitz_constraint_t constraint);
|
||||
|
@ -184,7 +184,7 @@ glitz_wgl_make_current_read (void *abstract_surface);
|
|||
extern void __internal_linkage
|
||||
glitz_wgl_destroy (void *abstract_drawable);
|
||||
|
||||
extern void __internal_linkage
|
||||
extern glitz_bool_t __internal_linkage
|
||||
glitz_wgl_swap_buffers (void *abstract_drawable);
|
||||
|
||||
extern void __internal_linkage
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -101,11 +101,271 @@ pixman_image_createForPixels (FbPixels *pixels,
|
|||
return image;
|
||||
}
|
||||
|
||||
static CARD32 xRenderColorToCard32(pixman_color_t c)
|
||||
{
|
||||
return
|
||||
(c.alpha >> 8 << 24) |
|
||||
(c.red >> 8 << 16) |
|
||||
(c.green & 0xff00) |
|
||||
(c.blue >> 8);
|
||||
}
|
||||
|
||||
static uint32_t premultiply(uint32_t x)
|
||||
{
|
||||
uint32_t a = x >> 24;
|
||||
uint32_t t = (x & 0xff00ff) * a + 0x800080;
|
||||
t = (t + ((t >> 8) & 0xff00ff)) >> 8;
|
||||
t &= 0xff00ff;
|
||||
|
||||
x = ((x >> 8) & 0xff) * a + 0x80;
|
||||
x = (x + ((x >> 8) & 0xff));
|
||||
x &= 0xff00;
|
||||
x |= t | (a << 24);
|
||||
return x;
|
||||
}
|
||||
|
||||
static uint32_t INTERPOLATE_PIXEL_256(uint32_t x, uint32_t a, uint32_t y, uint32_t b)
|
||||
{
|
||||
CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
|
||||
t >>= 8;
|
||||
t &= 0xff00ff;
|
||||
|
||||
x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
|
||||
x &= 0xff00ff00;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pixman_gradient_color (pixman_gradient_stop_t *stop1,
|
||||
pixman_gradient_stop_t *stop2,
|
||||
uint32_t x)
|
||||
{
|
||||
uint32_t current_color, next_color;
|
||||
int dist, idist;
|
||||
|
||||
current_color = xRenderColorToCard32 (stop1->color);
|
||||
next_color = xRenderColorToCard32 (stop2->color);
|
||||
|
||||
dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
|
||||
idist = 256 - dist;
|
||||
|
||||
return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
|
||||
next_color, dist));
|
||||
}
|
||||
|
||||
static int
|
||||
pixman_init_gradient_color_table (pixman_gradient_image_t *gradient,
|
||||
int tableSize)
|
||||
{
|
||||
int begin_pos, end_pos;
|
||||
xFixed incr, dpos;
|
||||
int pos, current_stop;
|
||||
pixman_gradient_stop_t *stops = gradient->stops;
|
||||
int nstops = gradient->nstops;
|
||||
|
||||
if (gradient->colorTableSize < tableSize)
|
||||
{
|
||||
uint32_t *newColorTable;
|
||||
|
||||
newColorTable = realloc (gradient->colorTable,
|
||||
tableSize * sizeof (uint32_t));
|
||||
if (!newColorTable)
|
||||
return 1;
|
||||
|
||||
gradient->colorTable = newColorTable;
|
||||
gradient->colorTableSize = tableSize;
|
||||
}
|
||||
|
||||
gradient->stopRange = tableSize;
|
||||
|
||||
/* The position where the gradient begins and ends */
|
||||
begin_pos = (stops[0].x * gradient->colorTableSize) >> 16;
|
||||
end_pos = (stops[nstops - 1].x * gradient->colorTableSize) >> 16;
|
||||
|
||||
pos = 0; /* The position in the color table. */
|
||||
|
||||
/* Up to first point */
|
||||
while (pos <= begin_pos) {
|
||||
gradient->colorTable[pos] = xRenderColorToCard32(stops[0].color);
|
||||
++pos;
|
||||
}
|
||||
|
||||
incr = (1<<16)/ gradient->colorTableSize; /* the double increment. */
|
||||
dpos = incr * pos; /* The position in terms of 0-1. */
|
||||
|
||||
current_stop = 0; /* We always interpolate between current and current + 1. */
|
||||
|
||||
/* Gradient area */
|
||||
while (pos < end_pos) {
|
||||
gradient->colorTable[pos] =
|
||||
pixman_gradient_color (&stops[current_stop],
|
||||
&stops[current_stop + 1],
|
||||
dpos);
|
||||
|
||||
++pos;
|
||||
dpos += incr;
|
||||
|
||||
if (dpos > stops[current_stop + 1].x)
|
||||
++current_stop;
|
||||
}
|
||||
|
||||
/* After last point */
|
||||
while (pos < gradient->colorTableSize) {
|
||||
gradient->colorTable[pos] =
|
||||
xRenderColorToCard32 (stops[nstops - 1].color);
|
||||
++pos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_pixman_init_gradient (pixman_gradient_image_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_fixed16_16_t dpos;
|
||||
int i;
|
||||
|
||||
if (n_stops <= 0)
|
||||
return 1;
|
||||
|
||||
dpos = -1;
|
||||
for (i = 0; i < n_stops; i++)
|
||||
{
|
||||
if (stops[i].x < dpos || stops[i].x > (1 << 16))
|
||||
return 1;
|
||||
|
||||
dpos = stops[i].x;
|
||||
}
|
||||
|
||||
gradient->class = SourcePictClassUnknown;
|
||||
gradient->stopRange = 0xffff;
|
||||
gradient->colorTable = NULL;
|
||||
gradient->colorTableSize = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pixman_image_t *
|
||||
_pixman_create_source_image (void)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
|
||||
image = (pixman_image_t *) malloc (sizeof (pixman_image_t));
|
||||
image->pDrawable = 0;
|
||||
image->pixels = 0;
|
||||
image->format_code = PICT_a8r8g8b8;
|
||||
|
||||
pixman_image_init (image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_linear_gradient_image_t *linear;
|
||||
pixman_image_t *image;
|
||||
|
||||
if (n_stops < 2)
|
||||
return 0;
|
||||
|
||||
image = _pixman_create_source_image ();
|
||||
if (!image)
|
||||
return 0;
|
||||
|
||||
linear = malloc (sizeof (pixman_linear_gradient_image_t) +
|
||||
sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
if (!linear)
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
linear->stops = (pixman_gradient_stop_t *) (linear + 1);
|
||||
linear->nstops = n_stops;
|
||||
|
||||
memcpy (linear->stops, stops, sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
|
||||
linear->type = SourcePictTypeLinear;
|
||||
linear->p1 = gradient->p1;
|
||||
linear->p2 = gradient->p2;
|
||||
|
||||
image->pSourcePict = (pixman_source_image_t *) linear;
|
||||
|
||||
if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_radial_gradient_image_t *radial;
|
||||
pixman_image_t *image;
|
||||
double x;
|
||||
|
||||
if (n_stops < 2)
|
||||
return 0;
|
||||
|
||||
image = _pixman_create_source_image ();
|
||||
if (!image)
|
||||
return 0;
|
||||
|
||||
radial = malloc (sizeof (pixman_radial_gradient_image_t) +
|
||||
sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
if (!radial)
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
radial->stops = (pixman_gradient_stop_t *) (radial + 1);
|
||||
radial->nstops = n_stops;
|
||||
|
||||
memcpy (radial->stops, stops, sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
|
||||
radial->type = SourcePictTypeRadial;
|
||||
x = (double) gradient->inner.radius / (double) gradient->outer.radius;
|
||||
radial->dx = (gradient->outer.x - gradient->inner.x);
|
||||
radial->dy = (gradient->outer.y - gradient->inner.y);
|
||||
radial->fx = (gradient->inner.x) - x * radial->dx;
|
||||
radial->fy = (gradient->inner.y) - x * radial->dy;
|
||||
radial->m = 1. / (1 + x);
|
||||
radial->b = -x * radial->m;
|
||||
radial->dx /= 65536.;
|
||||
radial->dy /= 65536.;
|
||||
radial->fx /= 65536.;
|
||||
radial->fy /= 65536.;
|
||||
x = gradient->outer.radius / 65536.;
|
||||
radial->a = x * x - radial->dx * radial->dx - radial->dy * radial->dy;
|
||||
|
||||
image->pSourcePict = (pixman_source_image_t *) radial;
|
||||
|
||||
if (_pixman_init_gradient (&image->pSourcePict->gradient, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void
|
||||
pixman_image_init (pixman_image_t *image)
|
||||
{
|
||||
image->refcnt = 1;
|
||||
image->repeat = 0;
|
||||
image->repeat = PIXMAN_REPEAT_NONE;
|
||||
image->graphicsExposures = 0;
|
||||
image->subWindowMode = ClipByChildren;
|
||||
image->polyEdge = PolyEdgeSharp;
|
||||
|
@ -135,16 +395,26 @@ pixman_image_init (pixman_image_t *image)
|
|||
image->serialNumber = GC_CHANGE_SERIAL_BIT;
|
||||
*/
|
||||
|
||||
image->pCompositeClip = pixman_region_create();
|
||||
pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip,
|
||||
0, 0, image->pixels->width, image->pixels->height);
|
||||
image->freeCompClip = 1;
|
||||
if (image->pixels)
|
||||
{
|
||||
image->pCompositeClip = pixman_region_create();
|
||||
pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip,
|
||||
0, 0, image->pixels->width,
|
||||
image->pixels->height);
|
||||
image->freeCompClip = 1;
|
||||
|
||||
image->pSourceClip = pixman_region_create ();
|
||||
pixman_region_union_rect (image->pSourceClip, image->pSourceClip,
|
||||
0, 0, image->pixels->width,
|
||||
image->pixels->height);
|
||||
image->freeSourceClip = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
image->pCompositeClip = NULL;
|
||||
image->pSourceClip = NULL;
|
||||
}
|
||||
|
||||
image->pSourceClip = pixman_region_create ();
|
||||
pixman_region_union_rect (image->pSourceClip, image->pSourceClip,
|
||||
0, 0, image->pixels->width, image->pixels->height);
|
||||
image->freeSourceClip = 1;
|
||||
|
||||
image->transform = NULL;
|
||||
|
||||
image->filter = PIXMAN_FILTER_NEAREST;
|
||||
|
@ -153,6 +423,8 @@ pixman_image_init (pixman_image_t *image)
|
|||
|
||||
|
||||
image->owns_pixels = 0;
|
||||
|
||||
image->pSourcePict = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -199,8 +471,8 @@ pixman_image_set_transform (pixman_image_t *image,
|
|||
}
|
||||
|
||||
void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
int repeat)
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
if (image)
|
||||
image->repeat = repeat;
|
||||
|
@ -218,25 +490,37 @@ pixman_image_set_filter (pixman_image_t *image,
|
|||
int
|
||||
pixman_image_get_width (pixman_image_t *image)
|
||||
{
|
||||
return image->pixels->width;
|
||||
if (image->pixels)
|
||||
return image->pixels->width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pixman_image_get_height (pixman_image_t *image)
|
||||
{
|
||||
return image->pixels->height;
|
||||
if (image->pixels)
|
||||
return image->pixels->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pixman_image_get_depth (pixman_image_t *image)
|
||||
{
|
||||
return image->pixels->depth;
|
||||
if (image->pixels)
|
||||
return image->pixels->depth;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pixman_image_get_stride (pixman_image_t *image)
|
||||
{
|
||||
return image->pixels->stride;
|
||||
if (image->pixels)
|
||||
return image->pixels->stride;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixman_format_t *
|
||||
|
@ -248,7 +532,10 @@ pixman_image_get_format (pixman_image_t *image)
|
|||
FbBits *
|
||||
pixman_image_get_data (pixman_image_t *image)
|
||||
{
|
||||
return image->pixels->data;
|
||||
if (image->pixels)
|
||||
return image->pixels->data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -276,6 +563,11 @@ pixman_image_destroy (pixman_image_t *image)
|
|||
image->transform = NULL;
|
||||
}
|
||||
|
||||
if (image->pSourcePict) {
|
||||
free (image->pSourcePict);
|
||||
image->pSourcePict = NULL;
|
||||
}
|
||||
|
||||
free (image);
|
||||
}
|
||||
slim_hidden_def(pixman_image_destroy);
|
||||
|
@ -307,6 +599,10 @@ pixman_image_set_clip_region (pixman_image_t *image,
|
|||
pixman_region_copy (image->clientClip, region);
|
||||
image->clientClipType = CT_REGION;
|
||||
}
|
||||
|
||||
image->stateChanges |= CPClipMask;
|
||||
if (image->pSourcePict)
|
||||
return 0;
|
||||
|
||||
if (image->freeCompClip)
|
||||
pixman_region_destroy (image->pCompositeClip);
|
||||
|
@ -326,7 +622,6 @@ pixman_image_set_clip_region (pixman_image_t *image,
|
|||
image->clipOrigin.y);
|
||||
}
|
||||
|
||||
image->stateChanges |= CPClipMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -377,7 +672,8 @@ FbClipImageSrc (pixman_region16_t *region,
|
|||
/* XXX what to do with clipping from transformed pictures? */
|
||||
if (image->transform)
|
||||
return 1;
|
||||
if (image->repeat)
|
||||
/* XXX davidr hates this, wants to never use source-based clipping */
|
||||
if (image->repeat != PIXMAN_REPEAT_NONE || image->pSourcePict)
|
||||
{
|
||||
/* XXX no source clipping */
|
||||
if (image->compositeClipSource &&
|
||||
|
|
|
@ -54,13 +54,92 @@ typedef struct pixman_format {
|
|||
} pixman_format_t;
|
||||
*/
|
||||
|
||||
#define PICT_GRADIENT_STOPTABLE_SIZE 1024
|
||||
|
||||
#define SourcePictTypeSolidFill 0
|
||||
#define SourcePictTypeLinear 1
|
||||
#define SourcePictTypeRadial 2
|
||||
#define SourcePictTypeConical 3
|
||||
|
||||
#define SourcePictClassUnknown 0
|
||||
#define SourcePictClassHorizontal 1
|
||||
#define SourcePictClassVertical 2
|
||||
|
||||
typedef struct _pixman_solid_fill_image {
|
||||
unsigned int type;
|
||||
unsigned int class;
|
||||
uint32_t color;
|
||||
} pixman_solid_fill_image_t;
|
||||
|
||||
typedef struct _pixman_gradient_image {
|
||||
unsigned int type;
|
||||
unsigned int class;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int nstops;
|
||||
int stopRange;
|
||||
uint32_t *colorTable;
|
||||
int colorTableSize;
|
||||
} pixman_gradient_image_t;
|
||||
|
||||
typedef struct _pixman_linear_gradient_image {
|
||||
unsigned int type;
|
||||
unsigned int class;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int nstops;
|
||||
int stopRange;
|
||||
uint32_t *colorTable;
|
||||
int colorTableSize;
|
||||
pixman_point_fixed_t p1;
|
||||
pixman_point_fixed_t p2;
|
||||
} pixman_linear_gradient_image_t;
|
||||
|
||||
typedef struct _pixman_radial_gradient_image {
|
||||
unsigned int type;
|
||||
unsigned int class;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int nstops;
|
||||
int stopRange;
|
||||
uint32_t *colorTable;
|
||||
int colorTableSize;
|
||||
double fx;
|
||||
double fy;
|
||||
double dx;
|
||||
double dy;
|
||||
double a;
|
||||
double m;
|
||||
double b;
|
||||
} pixman_radial_gradient_image_t;
|
||||
|
||||
typedef struct _pixman_conical_gradient_image {
|
||||
unsigned int type;
|
||||
unsigned int class;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int nstops;
|
||||
int stopRange;
|
||||
uint32_t *colorTable;
|
||||
int colorTableSize;
|
||||
pixman_point_fixed_t center;
|
||||
pixman_fixed16_16_t angle;
|
||||
} pixman_conical_gradient_image_t;
|
||||
|
||||
typedef union _pixman_source_image {
|
||||
unsigned int type;
|
||||
pixman_solid_fill_image_t solidFill;
|
||||
pixman_gradient_image_t gradient;
|
||||
pixman_linear_gradient_image_t linear;
|
||||
pixman_radial_gradient_image_t radial;
|
||||
pixman_conical_gradient_image_t conical;
|
||||
} pixman_source_image_t;
|
||||
|
||||
typedef pixman_source_image_t *SourcePictPtr;
|
||||
|
||||
struct pixman_image {
|
||||
FbPixels *pixels;
|
||||
pixman_format_t image_format;
|
||||
int format_code;
|
||||
int refcnt;
|
||||
|
||||
unsigned int repeat : 1;
|
||||
unsigned int repeat : 2;
|
||||
unsigned int graphicsExposures : 1;
|
||||
unsigned int subWindowMode : 1;
|
||||
unsigned int polyEdge : 1;
|
||||
|
@ -70,7 +149,7 @@ struct pixman_image {
|
|||
unsigned int clientClipType : 2;
|
||||
unsigned int componentAlpha : 1;
|
||||
unsigned int compositeClipSource : 1;
|
||||
unsigned int unused : 21;
|
||||
unsigned int unused : 20;
|
||||
|
||||
struct pixman_image *alphaMap;
|
||||
FbPoint alphaOrigin;
|
||||
|
@ -93,6 +172,8 @@ struct pixman_image {
|
|||
int filter_nparams;
|
||||
|
||||
int owns_pixels;
|
||||
|
||||
pixman_source_image_t *pSourcePict;
|
||||
};
|
||||
|
||||
#endif /* _ICIMAGE_H_ */
|
||||
|
|
|
@ -835,6 +835,13 @@ pixman_private pixman_image_t *
|
|||
pixman_image_createForPixels (FbPixels *pixels,
|
||||
pixman_format_t *format);
|
||||
|
||||
pixman_private uint32_t
|
||||
pixman_gradient_color (pixman_gradient_stop_t *stop1,
|
||||
pixman_gradient_stop_t *stop2,
|
||||
uint32_t x);
|
||||
|
||||
#define PictureGradientColor pixman_gradient_color
|
||||
|
||||
/* icpixels.c */
|
||||
|
||||
pixman_private FbPixels *
|
||||
|
|
|
@ -346,7 +346,7 @@ pixman_fill_rectangles (pixman_operator_t op,
|
|||
if (!src)
|
||||
goto bail2;
|
||||
|
||||
pixman_image_set_repeat (src, 1);
|
||||
pixman_image_set_repeat (src, PIXMAN_REPEAT_NORMAL);
|
||||
|
||||
while (nRects--)
|
||||
{
|
||||
|
|
|
@ -54,7 +54,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/* $Id: pixman.h,v 1.8 2005-10-06 04:02:08 vladimir%pobox.com Exp $ */
|
||||
/* $Id: pixman.h,v 1.11 2006-02-03 04:49:30 vladimir%pobox.com Exp $ */
|
||||
|
||||
/* libic.h */
|
||||
|
||||
|
@ -332,6 +332,34 @@ typedef struct pixman_transform {
|
|||
pixman_fixed16_16_t matrix[3][3];
|
||||
} pixman_transform_t;
|
||||
|
||||
typedef struct pixman_color {
|
||||
unsigned short red;
|
||||
unsigned short green;
|
||||
unsigned short blue;
|
||||
unsigned short alpha;
|
||||
} pixman_color_t;
|
||||
|
||||
typedef struct _pixman_gradient_stop {
|
||||
pixman_fixed16_16_t x;
|
||||
pixman_color_t color;
|
||||
} pixman_gradient_stop_t;
|
||||
|
||||
typedef struct _pixman_circle {
|
||||
pixman_fixed16_16_t x;
|
||||
pixman_fixed16_16_t y;
|
||||
pixman_fixed16_16_t radius;
|
||||
} pixman_circle_t;
|
||||
|
||||
typedef struct pixman_linear_gradient {
|
||||
pixman_point_fixed_t p1;
|
||||
pixman_point_fixed_t p2;
|
||||
} pixman_linear_gradient_t;
|
||||
|
||||
typedef struct pixman_radial_gradient {
|
||||
pixman_circle_t inner;
|
||||
pixman_circle_t outer;
|
||||
} pixman_radial_gradient_t;
|
||||
|
||||
typedef enum {
|
||||
PIXMAN_FILTER_FAST,
|
||||
PIXMAN_FILTER_GOOD,
|
||||
|
@ -348,9 +376,17 @@ int
|
|||
pixman_image_set_transform (pixman_image_t *image,
|
||||
pixman_transform_t *transform);
|
||||
|
||||
/* Don't blame me, blame XRender */
|
||||
typedef enum {
|
||||
PIXMAN_REPEAT_NONE,
|
||||
PIXMAN_REPEAT_NORMAL,
|
||||
PIXMAN_REPEAT_PAD,
|
||||
PIXMAN_REPEAT_REFLECT
|
||||
} pixman_repeat_t;
|
||||
|
||||
void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
int repeat);
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat);
|
||||
|
||||
void
|
||||
pixman_image_set_filter (pixman_image_t *image,
|
||||
|
@ -374,15 +410,17 @@ pixman_image_get_format (pixman_image_t *image);
|
|||
pixman_bits_t *
|
||||
pixman_image_get_data (pixman_image_t *image);
|
||||
|
||||
/* iccolor.c */
|
||||
pixman_image_t *
|
||||
pixman_image_create_linear_gradient (const pixman_linear_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
|
||||
/* XXX: Do we really need a struct here? Only pixman_rectangle_t uses this. */
|
||||
typedef struct pixman_color {
|
||||
unsigned short red;
|
||||
unsigned short green;
|
||||
unsigned short blue;
|
||||
unsigned short alpha;
|
||||
} pixman_color_t;
|
||||
pixman_image_t *
|
||||
pixman_image_create_radial_gradient (const pixman_radial_gradient_t *gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
|
||||
/* iccolor.c */
|
||||
|
||||
void
|
||||
pixman_color_to_pixel (const pixman_format_t *format,
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче