cairo landing: update to cairo 0.9.1+

This commit is contained in:
vladimir%pobox.com 2005-08-20 05:34:03 +00:00
Родитель 9cd9139cb6
Коммит cd33689aab
110 изменённых файлов: 25589 добавлений и 10171 удалений

Просмотреть файл

@ -42,7 +42,13 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = libpixman/src cairo/src
DIRS = $(NULL)
ifdef MOZ_ENABLE_GLITZ
DIRS += glitz/src
endif
DIRS += libpixman/src cairo/src
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -1,4 +1,4 @@
Snapshots of cairo and libpixman for mozilla usage. Where possible,
Snapshots of cairo, libpixman, and glitz for mozilla usage. Where possible,
these should be official releases from the cairo project as-is. If
changes are necessary, they should be documented below and the patch
file included in this directory.
@ -10,8 +10,9 @@ http://www.cairographics.org/.
VERSIONS:
cairo 0.5.0
cairo 0.9.1
libpixman 0.1.5
glitz 0.4.0
***** NOTE FOR VISUAL C++ 6.0 *****
@ -34,11 +35,4 @@ PATCHES:
allow-null-surface.diff - allow creating a cairo_t with a NULL
target surface
optimize-opaque-paint.diff - if cairo_paint_with_alpha is called
with alpha == 1.0, turn it into cairo_paint
win32-extents.diff - correct text extents for general tranforms
(upstream patch)
atsui-empty.diff - prevent OS-X crash with empty string

Просмотреть файл

@ -1,15 +0,0 @@
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo.c 2005-05-11 19:59:13.000000000 -0700
+++ cairo/src/cairo.c 2005-06-01 23:07:50.000000000 -0700
@@ -115,12 +115,6 @@
_cairo_path_fixed_init (&cr->path);
- if (target == NULL) {
- cr->gstate = NULL;
- cr->status = CAIRO_STATUS_NULL_POINTER;
- return cr;
- }
-
cr->gstate = _cairo_gstate_create (target);
if (cr->gstate == NULL)
cr->status = CAIRO_STATUS_NO_MEMORY;

Просмотреть файл

@ -1,3 +1,408 @@
Release 0.9.0 (2005-08-08 Carl Worth <cworth@cworth.org>)
=========================================================
API additions
-------------
* Add a new function call to set the current antialiasing mode in the
graphics state:
cairo_set_antialias
This call accepts the same modes recently added for font options
(NONE or GRAY) but affects the rendering of geometry other than
text. The intent of this call is to enable more precise control of
which pixels are affected by each operation, for example to allow
for full-scene antialiasing for seam-free rendering. It is not
expected that non-antialiased rendering will perform better than
anti-aliased rendering.
* Three new functions were added to provide support for mixed cairo-
and non-cairo drawing to the same surface:
cairo_surface_mark_dirty
cairo_surface_mark_dirty_rectangle
cairo_flush
* The return type of the several "reference" functions was change,
(API compatibly), from void to the same type as the argument. The
affected functions are:
cairo_font_face_reference
cairo_scaled_font_reference
cairo_pattern_reference
cairo_surface_reference
cairo_reference
This allows a convenient way to assign and reference in a single
statement.
cairo-win32
-----------
* Some portability improvements, (eg. workaround for missing stdint.h).
cairo-ft
--------
* Updated to allow compilation with older versions of freetype.
Bug fixes
---------
* Fix the unbounded operators to actually produce a correct result,
(previously the results were artificially restricited to the
bounding box of whatever shape was being drawn rather than
extending out infinitely). The fixed operators are:
CAIRO_OPERATOR_CLEAR
CAIRO_OPERATOR_SOURCE
CAIRO_OPERATOR_OUT
CAIRO_OPERATOR_IN
CAIRO_OPERATOR_DEST_IN
CAIRO_OPERATOR_DEST_ATOP
* Fix cairo_mask and cairo_mask_surface to transform the mask by the
current transformation matrix (CTM).
* Fix cairo_set_source to lock the CTM used to transform the pattern.
* Workaround for X server Render bug involving repeating patterns
with a general transformation matrix.
* cairo_get_font_face fixed to return a "nil" font face object rather
than NULL on error.
* cairo_set_font_face fixed to not crash if given a NULL font face,
(which is the documented interface for restoring the defauly font
face).
* Fix xlib glyphset caching to not try to free a NULL glyph.
Snapshot 0.6.0 (2005-07-28 Carl Worth <cworth@cworth.org>)
==========================================================
API changes
-----------
* The prototypes of the following functions have changed:
cairo_xlib_surface_create_with_xrender_format
cairo_xlib_surface_create_for_bitmap
A Screen* parameter has been added to each. This allows the cairo
xlib backend to work correctly with multi-head X servers.
* The following function has been modified:
cairo_scaled_font_create
to accept a cairo_font_options_t*. See below fore more details.
* All opaque, reference-counted cairo objects have now been moved to a
standard error-handling scheme. The new objects to receive this
treatment are cairo_font_face_t, cairo_scaled_font_t, and
cairo_surface_t. (Previous snapshots already provided this scheme
for cairo_t, cairo_path_t, and cairo_pattern_t.)
This changes two functions to have a return type of void rather than
cairo_status_t:
cairo_scaled_font_extent
cairo_surface_finish
And significantly, none of the create functions for any of the
objects listed above will return NULL. The pointer returned from any
function will now always be a valid pointer and should always be
passed to the corresponding destroy function when finished
The simplest strategy for porting code is to switch from:
object = cairo_<object>_create ();
if (object == NULL)
goto BAILOUT;
/* act on object */
cairo_<object>_destroy (object);
to:
object = cairo_<object>_create ();
if (cairo_<object>_status (object))
goto BAILOUT;
/* act on object */
cairo_<object>_destroy (object);
But significantly, it is not required to check for an error status
before the "act on object" portions of the code above. All
operations on an object with an error status are, by definition,
no-ops without side effect. So new code might be written in an
easier-to-read style of:
object = cairo_<object>_create ();
/* act on object */
cairo_<object>_destroy (object);
with cairo_<object>_status checks placed only at strategic
locations. For example, passing an error object to another object,
(eg. cairo_set_source with an in-error pattern), will propagate the
error to the subsequent object (eg. the cairo_t). This means that
error checking can often be deferred even beyond the destruction of
a temporary object.
API additions
-------------
* New functions for checking the status of objects that have been
switched to the common error-handling scheme:
cairo_font_face_status
cairo_scaled_font_status
cairo_surface_status
* The _cairo_error function which was added in 0.5.1 has now been made
much more useful. In 0.5.1 only errors on cairo_t objects passed
through _cairo_error. Now, an error on any object should pass
through _cairo_error making it much more reliable as a debugging
mechanism for finding when an error first occurs.
* Added new font options support with a myriad of functions:
cairo_font_options_create
cairo_font_options_copy
cairo_font_options_destroy
cairo_font_options_status
cairo_font_options_merge
cairo_font_options_equal
cairo_font_options_hash
cairo_font_options_set_antialias
cairo_font_options_get_antialias
cairo_font_options_set_subpixel_order
cairo_font_options_get_subpixel_order
cairo_font_options_set_hint_style
cairo_font_options_get_hint_style
cairo_font_options_set_hint_metrics
cairo_font_options_get_hint_metrics
cairo_surface_get_font_options
cairo_ft_font_options_substitute
cairo_set_font_options
cairo_get_font_options
This new font options support allows the application to have much
more fine-grained control over how fonts are rendered.
Significantly, it also allows surface backends to have some
influence over the process. For example, the xlib backend now
queries existing Xft properties to set font option defaults.
* New function:
cairo_xlib_surface_set_drawable
which allos the target drawable for an xlib cairo_surface_t to be
changed to another with the same format, screen, and display. This
is necessary in certain double-buffering techniques.
New features
------------
* Sub-pixel text antialiasing is now supported.
Bug fixes
---------
* Fixed assertion failure in cairo_surface_create_similar when
application commits an error by passing a cairo_format_t rather than
a cairo_content_t.
* Avoid division by zero in various places (cairo-ft).
* Fix infinite loop when using non-default visuals (cairo-xlib).
* Eliminate segfault in cairo_image_surface_create_from_png_stream.
* Prevent errant sign-extension of masks on 64-bit architectures
(cairo-xlib and cairo-xcb).
* Other miscellaneous fixes.
Snapshot 0.5.2 (2005-07-18 Carl Worth <cworth@cworth.org>)
==========================================================
API changes
-----------
* New functions for creating patterns of a single color:
cairo_pattern_create_rgb
cairo_pattern_create_rgba
* Change cairo_surface_create_similar to accept a new type of
cairo_content_t rather than cairo_format_t:
typedef enum _cairo_content {
CAIRO_CONTENT_COLOR = 0x1000,
CAIRO_CONTENT_ALPHA = 0x2000,
CAIRO_CONTENT_COLOR_ALPHA = 0x3000
} cairo_content_t;
* Add new CAIRO_FORMAT_VALID and CAIRO_CONTENT_VALID macros.
* Remove unused status value:
CAIRO_STATUS_NO_TARGET_SURFACE
* Add new status values:
CAIRO_STATUS_INVALID_STATUS
* Require libpixman >= 0.1.5 (for necessary bug fixes)
Bug fixes
---------
* Fix cairo_surface_write_to_png for RGB24 images.
* Fix broken metrics and rendering for bitmap fonts. Add mostly
useless bitmap glyph transformation.
* Fix glyph caches to not eject entries that might be immediately
needed, (fixing intermittent crashes when rendering text).
* Fix all memory leaks found by running "make check-valigrind".
ATSUI backend changes
---------------------
* Allow building against < 10.3 SDK.
* Prevent crash on empty strings.
Glitz backend changes
---------------------
* Require glitz >= 0.4.4.
* Use frame buffer objects instead of pbuffers for accelerated
offscreen drawing.
* Minor improvement to gradient pattern creation.
PostScript backend fixes
------------------------
* Rewrite of the PS backend to generate more interesting output that
the old big-image implementation.
Win32 backend fixes
-------------------
* Implement glyph path support.
* Fix swap of blue and green values in the fill_rectangles path.
Xlib backend fixes
------------------
* Add optimization to use XCopyArea rather than XRenderComposite when
transforming only with an integer translation, and using SOURCE
operator or OVER with a source pattern without alpha.
Snapshot 0.5.1 (2005-06-20 Carl Worth <cworth@cworth.org>)
==========================================================
API changes
-----------
* Removed cairo_status_string(cairo_t*) and add
cairo_status_to_string(cairo_status_t) in its place. Code using
cairo_status_string can be ported forward as follows:
cairo_status (cr);
->
cairo_status_to_string (cairo_status (cr));
* Removed the BAD_NESTING restriction which means that two different
cairo_t objects can now interleave drawing to the same
cairo_surface_t without causing an error.
* The following functions which previously had a return type of
cairo_status_t now have a return type of void:
cairo_pattern_add_color_stop_rgba
cairo_pattern_set_matrix
cairo_pattern_get_matrix
cairo_pattern_set_extend
cairo_pattern_set_filter
See discussion of cairo_pattern_status below for more details.
API additions
-------------
* Improved error handling:
cairo_status_t
cairo_pattern_status (cairo_pattern_t *pattern);
This snapshot expands the status-based error handling scheme from
cairo_t to cairo_path_t and cairo_pattern_t. It also expands the
scheme so that object-creating functions, (cairo_create,
cairo_pattern_create_*, cairo_copy_path_*), are now guaranteed to
not return NULL. Instead, in the case of out-of-memory these
functions will return a static object with
status==CAIRO_STATUS_NO_MEMORY. The status can be checked with the
functions cairo_status and cairo_pattern_status, or by direct
inspection of the new status field in cairo_path_t.
Please note that some objects, including cairo_surface_t and all of
the font-related objects have not been converted to this
error-handling scheme.
* In addition to the above changes, a new private function has been added:
_cairo_error
This function can be used to set a breakpoint in a debugger to make
it easier to find programming error in cairo-using code. (Currently,
_cairo_error is called when any error is detected within a cairo_t
context, but is not called for non-cairo_t errors such as for
cairo_path_t and cairo_pattern_t).
* Fixed cairo_path_data_t so that its enum is visible to C++ code, (as
cairo_path_data_type_t).
Performance improvements
------------------------
* Made a minor performance improvement for clipping, (restrict clip
surface to the new intersected bounds).
* Optimize rendering of a solid source pattern with a pixel-aligned
rectangular path to use backend clipping rather than rasterization
and backend compositing.
* Optimize cairo_paint_with_alpha to defer to cairo_paint when alpha
is 1.0.
Bug fixes
---------
* Fixed memory leak in cairo_copy_path.
* A build fix for non-srcdir builds.
PDF backend fixes
-----------------
* New support for path-based clipping.
* Fix for text rotated to angles other than multiples of π/2.
Win32 backend fixes
-------------------
* Fix for text extents.
Xlib backend
------------
* Implemented a complex workaround for X server bug[*] related to
Render-based compositing with untransformed, repeating source
pictures. The workaround uses core Xlib when possible for
performance, (ie. with CAIRO_OPERATOR_SOURCE or CAIRO_OPERATOR_OVER
with an opaque source surface), and falls back to the pixman
image-based compositing otherwise.
[*] https://bugs.freedesktop.org/show_bug.cgi?id=3566
* Various bug fixes, particularly in the fallback paths.
Snapshot 0.5.0 (2005-05-17 Carl Worth <cworth@cworth.org>)
==========================================================
This is a pretty big, and fairly significant snapshot. It represents

Просмотреть файл

@ -1,105 +1,40 @@
API Shakeup planning
--------------------
Changes that are expected to impact the public API
==================================================
Patch submitted to mailing list?
/ Documentation included in patch?
|/ Review of patch completed?
||/ Test case included?
|||/ Committed.
||||/
New functionality (more-or-less)
--------------------------------
Backwards compatible (API additions only)
-----------------------------------------
cairo_begin_group, cairo_end_group, cairo_get_group
cairo_<device>_surface_mark_dirty
Consistent error handling for all objects
PDR C cairo_surface_mark_dirty (see below for details)
PDRTC Add support for non-antialiased rendering + API
Add CAIRO_FILL_RULE_INVERSE_WINDING and CAIRO_FILL_RULE_INVERSE_EVEN_ODD
Add cairo_text_glyphs (see below for details)
Add support for programmatic patterns, (ie. arbitrary gradients)
P Add cairo_arc_to.
Add support for custom caps (see below for details)
Add support for getting at image data from image surface
Add CAIRO_STATUS_DESTROYED
Add cairo_finish
Somewhat backwards-compatible changes
-----------------------------------
PDRTC user data (was Re: [cairo] Patch improving fallbacks)
PDRTC setters and getters
PDRTC cairo_output_stream_t and cairo_surface_finish()
PDRTC cairo_current_path -> cairo_copy_path_data
Backwards incompatible (API deletions or changes)
-------------------------------------------------
PDR C cairo_surface_finish, cairo_surface_flush
PDRTC Abbreviation hunt: cairo_init_clip and cairo_concat_matrix
PDRTC Renaming the terms of the rendering equation
PDRTC default matrix
PDRTC cairo_paint
PDRTC Making set_source consistent
PDRTC cairo_stroke_path -> cairo_stroke_to_path
PDRTC cairo_current_matrix
PDRTC cairo_mask
PDRTC cairo_fill_preserve, cairo_stroke_preserve, cairo_clip_preserve
PDR C A hidden offset for the xlib backend
PDR C Consistent error handling for all objects
PDRTC Split cairo_format_t (see below for details)
P---C Remove cairo_status_string in favor of cairo_status_to_string
Backwards incompatible
----------------------
PDRTC Simplifying the operator set
PDRTC cairo_create and eliminating cairo_set_target_surface
PDRTC Eliminating cairo_copy
PDRTC Eliminating cairo_surface_set_repeat/matrix/filter
PDRTC Eliminating cairo_show_surface
Details on some of the above changes
------------------------------------
* cairo_text_glyphs:
* Add support for non-antialiased rendering. API ?
* Clean up the cache code a bit, (there is at least one redundant
level of cacheing, and there are some minor style issues).
* Add CAIRO_FILL_RULE_INVERSE_WINDING and CAIRO_FILL_RULE_INVERSE_EVEN_ODD
* Fix clipping to work for all operators. The equation we have come up
with is:
((src Op dest) In clip) Add (dest Out clip)
* Split cairo_format_t into two things:
- An enumeration that determines the "capabilities" of a surface -
A vs. ARGB. vs. RGB
- An enumeration that determines a specific in-memory representation
of data. (A1/A8/ARGB32/etc.. Could be extensible to things like
RGBA32_BYTES_NONPREMULTIPLIED. Some consistent naming convention would
be be good.)
One issue here is that some interfaces, like cairo_surface_create_similar()
might be useful with either one. We might want to create an A1 surface
compatible with the backend (are there examples other than A1? Should
bilevel just be another "capability"?), or we might want to just create
an alpha surface without caring about the depth.
If we want to support this, we could do something like:
typedef enum cairo_pixel_format_t {
CAIRO_PIXEL_FORMAT_A8 = CAIRO_FORMAT_ALPHA,
CAIRO_PIXEL_FORMAT_RGB24 = CAIRO_FORMAT_RGB,
CAIRO_PIXEL_FORMAT_A1,
};
To allow passing either in.
(I don't particularly like this idea for create_similar() because then you
aren't really saying ALPHA-dont-care, you are saying ALPHA-8. I think it
would be better to have a separate path for create_similar_with_pixel_format()
if we need that. But it might be useful for cairo_image_surface_create() ...
people are going to screw up and pass CAIRO_FORMAT_RGB into that, and if it
"just worked" that would save people trouble....)
* Clean up the API in preparation for freezing and release.
* Make a more interesting PS backend, (other than the current
"giant-image for every page" approach).
* Figure out what to do with DPI for image/png backends.
* Change stroke code to go through one giant polygon. This will fix
problems with stroking self-intersecting paths.
* Re-work the backend clipping interface to use geometry rather than
images.
* Fix the intersection problem, (see reference to Hobby's paper
mentioned in cairo_traps.c).
* Add a new cairo_text_glyphs function (a sort of bridge between the
toy and the real text API):
It would function as a sort of bridge between the toy and the
real text APIs:
> void
> cairo_text_glyphs (cairo_t *cr, const unsigned char *utf8,
@ -118,56 +53,34 @@ toy and the real text API):
> as long as the original size of glyphs/num_glyphs was large
> enough.
* Implement dashing for cairo_curve_to.
* support for custom caps:
* Implement support for programmatic patterns, (ie. figure out how to
do gradients the Right Way).
* Implement cairo_arc_to.
* Stroking closed, degenerate paths should still draw caps. Round
caps are easy; square should probably draw an axis-aligned square.
* It would be nice if the user had a mechanism to reliably draw custom
It would be nice if the user had a mechanism to reliably draw custom
caps. One approach here would be to provide the coordinates of the
butt cap faces so that the user can append seamless caps to the
current path. We may also need to provide the coordinates of the
faces of every dash as well.
Changes that do not affect the public API
=========================================
* Fix clipping to work for all operators. The equation we have come up
with is:
((src Op dest) In clip) Add (dest Out clip)
* Change stroke code to go through one giant polygon. This will fix
problems with stroking self-intersecting paths.
* Fix the intersection problem, (see reference to Hobby's paper
mentioned in cairo_traps.c).
* Implement dashing for cairo_curve_to.
* Stroking closed, degenerate paths should still draw caps. Round
caps are easy; square should probably draw an axis-aligned square.
* Should add geometry pruning as appropriate.
* We need a way to get at the image data after something
like cairo_surface_create_similar with the image backend.
* Three suggestions from Owen that will help GTK+ performance:
- The ability have an additional rectangle-list clip in the
Xlib surface. Frequently during an expose event, GTK+ is
drawing L shaped areas
XXXXXX
X.....
X.....
And passing the real clip to the server is going to save
a lot of pixel operations that will be thrown away.
- The ability to pass in a width/height to cairo_xlib_surface_create()
to avoid a round-trip. (Round-trips are bad to the point where
querying the the server is something you don't want to do in
production software)
- More of a future thing, the ability to hint to to cairo that
the contents of the Xlib surface passed to
cairo_xlib_surface_create() are a solid fill ... this is
very much the normal case for GTK+ usage and allows for
big optimization in the no-RENDER case.
(see http://mail.gnome.org/archives/gtk-devel-list/2003-March/msg00045.html
* Verification, profiling, optimization.
centi_unfinished.svg may provide a good test case.
* Implement copy-on-write regions in pixman as a more complete
solution than the BAD_NESTING stuff to Owen's "Clip region problems"
thread.

Просмотреть файл

@ -36,88 +36,97 @@
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = cairo
LIBRARY_NAME = mozcairo
MODULE = cairo
LIBRARY_NAME = mozcairo
LIBXUL_LIBRARY = 1
REQUIRES = $(PNG_REQUIRES) \
$(ZLIB_REQUIRES) \
libpixman \
$(NULL)
REQUIRES = $(PNG_REQUIRES) \
$(ZLIB_REQUIRES) \
libpixman \
$(NULL)
CSRCS = \
cairo.c \
cairo-arc.c \
cairo-array.c \
cairo-cache.c \
cairo-color.c \
cairo-fixed.c \
cairo-font.c \
cairo-gstate.c \
cairo-hull.c \
cairo-image-surface.c \
cairo-matrix.c \
cairo-output-stream.c \
cairo-path.c \
cairo-path-bounds.c \
cairo-path-data.c \
cairo-path-fill.c \
cairo-path-stroke.c \
cairo-pattern.c \
cairo-pen.c \
cairo-polygon.c \
cairo-slope.c \
cairo-spline.c \
cairo-surface.c \
cairo-traps.c \
cairo-unicode.c \
cairo-wideint.c \
$(NULL)
CSRCS = \
cairo.c \
cairo-arc.c \
cairo-array.c \
cairo-cache.c \
cairo-clip.c \
cairo-color.c \
cairo-debug.c \
cairo-fixed.c \
cairo-font.c \
cairo-font-options.c \
cairo-gstate.c \
cairo-hash.c \
cairo-hull.c \
cairo-image-surface.c \
cairo-matrix.c \
cairo-meta-surface.c \
cairo-output-stream.c \
cairo-path.c \
cairo-path-bounds.c \
cairo-path-data.c \
cairo-path-fill.c \
cairo-path-stroke.c \
cairo-pattern.c \
cairo-pen.c \
cairo-polygon.c \
cairo-region.c \
cairo-slope.c \
cairo-spline.c \
cairo-surface.c \
cairo-traps.c \
cairo-unicode.c \
cairo-wideint.c \
$(NULL)
EXPORTS = cairo.h cairo-features.h
EXPORTS = cairo.h cairo-features.h
ifeq ($(MOZ_GFX_TOOLKIT),windows)
CSRCS += cairo-win32-font.c \
cairo-win32-surface.c
CSRCS += cairo-win32-font.c \
cairo-win32-surface.c
EXPORTS += cairo-win32.h
endif
ifneq (,$(filter mac cocoa,$(MOZ_GFX_TOOLKIT)))
CSRCS += cairo-quartz-surface.c \
cairo-atsui-font.c
EXPORTS += cairo-quartz.h
CSRCS += cairo-quartz-surface.c \
cairo-atsui-font.c
EXPORTS += cairo-quartz.h cairo-atsui.h
endif
ifdef BUILD_CAIRO_PDF
CSRCS += cairo-pdf-surface.c \
cairo-ps-surface.c
CSRCS += cairo-font-subset.c \
cairo-pdf-surface.c \
cairo-ps-surface.c
EXPORTS += cairo-ps.h cairo-pdf.h
endif
ifdef MOZ_X11
CSRCS += cairo-xlib-surface.c \
cairo-ft-font.c
EXPORTS += cairo-xlib.h
CSRCS += cairo-xlib-surface.c \
cairo-xlib-screen.c \
cairo-ft-font.c
EXPORTS += cairo-xlib.h cairo-xlib-xrender.h cairo-ft.h
LOCAL_INCLUDES += $(FT2_CFLAGS)
endif
ifdef BUILD_CAIRO_GL
CSRCS += cairo-glitz-surface.c
EXPORTS += cairo-glitz.h
ifdef MOZ_ENABLE_GLITZ
REQUIRES += glitz
CSRCS += cairo-glitz-surface.c
EXPORTS += cairo-glitz.h
endif
LOCAL_INCLUDES += -I$(srcdir)
LOCAL_INCLUDES += -I$(srcdir)
FORCE_STATIC_LIB = 1
# This library is used by other shared libs in a static build

Просмотреть файл

@ -38,7 +38,7 @@
#include "cairoint.h"
void
cairo_private void
_cairo_arc_path (cairo_t *cr,
double xc,
double yc,
@ -46,7 +46,7 @@ _cairo_arc_path (cairo_t *cr,
double angle1,
double angle2);
void
cairo_private void
_cairo_arc_path_negative (cairo_t *cr,
double xc,
double yc,

Просмотреть файл

@ -100,6 +100,8 @@ _arc_max_angle_for_tolerance_normalized (double tolerance)
return angle;
}
/* XXX: The computation here if bogus. Correct math (with proof!) is
* available in _cairo_pen_vertices_needed. */
static int
_arc_segments_needed (double angle,
double radius,

Просмотреть файл

@ -147,7 +147,7 @@ typedef struct {
*
* Initializes a #cairo_user_data_array_t structure for future
* use. After initialization, the array has no keys. Call
* _cairo_user_data_array_destroy() to free any allocated memory
* _cairo_user_data_array_fini() to free any allocated memory
* when done using the array.
**/
void
@ -157,14 +157,14 @@ _cairo_user_data_array_init (cairo_user_data_array_t *array)
}
/**
* _cairo_user_data_array_destroy:
* _cairo_user_data_array_fini:
* @array: a #cairo_user_data_array_t
*
* Destroys all current keys in the user data array and deallocates
* any memory allocated for the array itself.
**/
void
_cairo_user_data_array_destroy (cairo_user_data_array_t *array)
_cairo_user_data_array_fini (cairo_user_data_array_t *array)
{
int i, num_slots;
cairo_user_data_slot_t *slots;
@ -198,6 +198,11 @@ _cairo_user_data_array_get_data (cairo_user_data_array_t *array,
int i, num_slots;
cairo_user_data_slot_t *slots;
/* We allow this to support degenerate objects such as
* cairo_image_surface_nil. */
if (array == NULL)
return NULL;
num_slots = array->num_elements;
slots = (cairo_user_data_slot_t *) array->elements;
for (i = 0; i < num_slots; i++) {

Просмотреть файл

@ -68,7 +68,6 @@ typedef struct cairo_ATSUI_glyph_path_callback_info_t {
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend;
static CGAffineTransform
CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
{
@ -77,7 +76,6 @@ CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
0, 0);
}
static ATSUStyle
CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale)
{
@ -107,12 +105,11 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale)
static cairo_status_t
_cairo_atsui_font_create(const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
cairo_scaled_font_t **font_out)
_cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_scaled_font_t **font_out)
{
cairo_atsui_font_t *font = NULL;
ATSUStyle style;
@ -120,11 +117,11 @@ _cairo_atsui_font_create(const char *family,
OSStatus err;
Boolean isItalic, isBold;
cairo_matrix_t scale;
const char *family = toy_face->family;
err = ATSUCreateStyle(&style);
switch (weight) {
switch (toy_face->weight) {
case CAIRO_FONT_WEIGHT_BOLD:
isBold = true;
break;
@ -134,7 +131,7 @@ _cairo_atsui_font_create(const char *family,
break;
}
switch (slant) {
switch (toy_face->slant) {
case CAIRO_FONT_SLANT_ITALIC:
isItalic = true;
break;
@ -190,7 +187,7 @@ _cairo_atsui_font_create(const char *family,
font = malloc(sizeof(cairo_atsui_font_t));
_cairo_scaled_font_init(&font->base, font_matrix, ctm,
_cairo_scaled_font_init(&font->base, toy_face, font_matrix, ctm, options,
&cairo_atsui_scaled_font_backend);
cairo_matrix_multiply(&scale, font_matrix, ctm);
@ -215,13 +212,11 @@ _cairo_atsui_font_create(const char *family,
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_atsui_font_destroy_font(void *abstract_font)
_cairo_atsui_font_fini(void *abstract_font)
{
cairo_atsui_font_t *font = abstract_font;
if (font == NULL)
return;
@ -501,14 +496,16 @@ _cairo_atsui_font_show_glyphs(void *abstract_font,
CGContextSetTextMatrix(myBitmapContext, textTransform);
if (pattern->type == CAIRO_PATTERN_SOLID &&
_cairo_pattern_is_opaque_solid(pattern)) {
_cairo_pattern_is_opaque_solid(pattern))
{
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
CGContextSetRGBFillColor(myBitmapContext,
solid->color.red,
solid->color.green,
solid->color.blue, 1.0f);
} else
} else {
CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f);
}
// TODO - bold and italic text
//
@ -690,10 +687,9 @@ _cairo_atsui_font_glyph_path(void *abstract_font,
return CAIRO_STATUS_SUCCESS;
}
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
_cairo_atsui_font_create,
_cairo_atsui_font_destroy_font,
_cairo_atsui_font_create_toy,
_cairo_atsui_font_fini,
_cairo_atsui_font_font_extents,
_cairo_atsui_font_text_to_glyphs,
_cairo_atsui_font_glyph_extents,

Просмотреть файл

@ -38,7 +38,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_ATSUI_FONT
#if CAIRO_HAS_ATSUI_FONT
/* ATSUI platform-specific font interface */

Просмотреть файл

@ -182,19 +182,25 @@ _cache_lookup (cairo_cache_t *cache,
{
/* We are looking up an exact entry. */
if (*probe == NULL)
{
/* Found an empty spot, there can't be a match */
break;
}
else if (*probe != DEAD_ENTRY
&& (*probe)->hashcode == hash
&& predicate (cache, key, *probe))
{
return probe;
}
}
else
{
/* We are just looking for a free slot. */
if (*probe == NULL
|| *probe == DEAD_ENTRY)
{
return probe;
}
}
if (step == 0) {
@ -339,7 +345,6 @@ _cairo_cache_init (cairo_cache_t *cache,
if (cache != NULL){
cache->arrangement = &cache_arrangements[0];
cache->refcount = 1;
cache->max_memory = max_memory;
cache->used_memory = 0;
cache->live_entries = 0;
@ -361,31 +366,33 @@ _cairo_cache_init (cairo_cache_t *cache,
return CAIRO_STATUS_SUCCESS;
}
void
_cairo_cache_reference (cairo_cache_t *cache)
{
_cache_sane_state (cache);
cache->refcount++;
}
void
_cairo_cache_destroy (cairo_cache_t *cache)
{
unsigned long i;
if (cache != NULL) {
if (cache == NULL)
return;
_cache_sane_state (cache);
_cache_sane_state (cache);
if (--cache->refcount > 0)
return;
for (i = 0; i < cache->arrangement->size; ++i)
_entry_destroy (cache, i);
for (i = 0; i < cache->arrangement->size; ++i) {
_entry_destroy (cache, i);
}
free (cache->entries);
cache->entries = NULL;
cache->backend->destroy_cache (cache);
free (cache->entries);
cache->entries = NULL;
cache->backend->destroy_cache (cache);
}
void
_cairo_cache_shrink_to (cairo_cache_t *cache,
unsigned long max_memory)
{
unsigned long idx;
/* Make some entries die if we're under memory pressure. */
while (cache->live_entries > 0 && cache->used_memory > max_memory) {
idx = _random_entry (cache, NULL) - cache->entries;
assert (idx < cache->arrangement->size);
_entry_destroy (cache, idx);
}
}
@ -396,7 +403,6 @@ _cairo_cache_lookup (cairo_cache_t *cache,
int *created_entry)
{
unsigned long idx;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_cache_entry_base_t **slot = NULL, *new_entry;
@ -446,14 +452,8 @@ _cairo_cache_lookup (cairo_cache_t *cache,
/* Store the hash value in case the backend forgot. */
new_entry->hashcode = cache->backend->hash (cache, key);
/* Make some entries die if we're under memory pressure. */
while (cache->live_entries > 0 &&
cache->max_memory > 0 &&
((cache->max_memory - cache->used_memory) < new_entry->memory)) {
idx = _random_entry (cache, NULL) - cache->entries;
assert (idx < cache->arrangement->size);
_entry_destroy (cache, idx);
}
if (cache->live_entries && cache->max_memory)
_cairo_cache_shrink_to (cache, cache->max_memory);
/* Can't assert this; new_entry->memory may be larger than max_memory */
/* assert(cache->max_memory >= (cache->used_memory + new_entry->memory)); */
@ -512,7 +512,7 @@ _cairo_hash_string (const char *c)
{
/* This is the djb2 hash. */
unsigned long hash = 5381;
while (*c)
while (c && *c)
hash = ((hash << 5) + hash) + *c++;
return hash;
}

Просмотреть файл

@ -0,0 +1,123 @@
/* 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):
* Kristian Høgsberg <krh@redhat.com>
*/
#ifndef CAIRO_CLIP_PRIVATE_H
#define CAIRO_CLIP_PRIVATE_H
#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;
cairo_fill_rule_t fill_rule;
double tolerance;
cairo_antialias_t antialias;
cairo_clip_path_t *prev;
};
struct _cairo_clip {
cairo_clip_mode_t mode;
/*
* Mask-based clipping for cases where the backend
* clipping isn't sufficiently able.
*
* The rectangle here represents the
* portion of the destination surface that this
* clip surface maps to, it does not
* represent the extents of the clip region or
* clip paths
*/
cairo_surface_t *surface;
cairo_rectangle_t surface_rect;
/*
* Surface clip serial number to store
* in the surface when this clip is set
*/
unsigned int serial;
/*
* A clip region that can be placed in the surface
*/
pixman_region16_t *region;
/*
* If the surface supports path clipping, we store the list of
* clipping paths that has been set here as a linked list.
*/
cairo_clip_path_t *path;
};
cairo_private void
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
cairo_private void
_cairo_clip_fini (cairo_clip_t *clip);
cairo_private void
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
cairo_private cairo_status_t
_cairo_clip_reset (cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_clip_clip (cairo_clip_t *clip,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
cairo_rectangle_t *rectangle);
cairo_private cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
pixman_region16_t *region);
cairo_private cairo_status_t
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
cairo_operator_t operator,
cairo_surface_t *dst,
int dst_x,
int dst_y,
const cairo_rectangle_t *extents);
#endif /* CAIRO_CLIP_PRIVATE_H */

Просмотреть файл

@ -0,0 +1,437 @@
/* 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>
* Kristian Høgsberg <krh@redhat.com>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
static cairo_clip_path_t *
_cairo_clip_path_reference (cairo_clip_path_t *clip_path);
static void
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
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->serial = 0;
clip->path = NULL;
}
void
_cairo_clip_fini (cairo_clip_t *clip)
{
if (clip->surface)
cairo_surface_destroy (clip->surface);
clip->surface = NULL;
if (clip->path)
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
if (clip->region)
pixman_region_destroy (clip->region);
clip->region = NULL;
clip->serial = 0;
}
void
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
{
if (other->region) {
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;
}
cairo_status_t
_cairo_clip_reset (cairo_clip_t *clip)
{
/* destroy any existing clip-region artifacts */
if (clip->surface)
cairo_surface_destroy (clip->surface);
clip->surface = NULL;
if (clip->region)
pixman_region_destroy (clip->region);
clip->region = NULL;
if (clip->path)
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
clip->serial = 0;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
cairo_rectangle_t *rectangle)
{
if (clip->path) {
/* Intersect path extents here. */
}
if (clip->region) {
pixman_region16_t *intersection;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
pixman_region_status_t pixman_status;
intersection = _cairo_region_create_from_rectangle (rectangle);
if (intersection == NULL)
return CAIRO_STATUS_NO_MEMORY;
pixman_status = pixman_region_intersect (intersection,
clip->region,
intersection);
if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
_cairo_region_extents_rectangle (intersection, rectangle);
else
status = CAIRO_STATUS_NO_MEMORY;
pixman_region_destroy (intersection);
if (status)
return status;
}
if (clip->surface)
_cairo_rectangle_intersect (rectangle, &clip->surface_rect);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
pixman_region16_t *region)
{
if (clip->path) {
/* Intersect clip path into region. */
}
if (clip->region)
pixman_region_intersect (region, clip->region, region);
if (clip->surface) {
pixman_region16_t *clip_rect;
pixman_region_status_t pixman_status;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
if (clip_rect == NULL)
return CAIRO_STATUS_NO_MEMORY;
pixman_status = pixman_region_intersect (region,
clip_rect,
region);
if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
status = CAIRO_STATUS_NO_MEMORY;
pixman_region_destroy (clip_rect);
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
/* Combines the region of clip->surface given by extents in
* device backend coordinates into the given temporary surface,
* which has its origin at dst_x, dst_y in backend coordinates
*/
cairo_status_t
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
cairo_operator_t operator,
cairo_surface_t *dst,
int dst_x,
int dst_y,
const cairo_rectangle_t *extents)
{
cairo_pattern_union_t pattern;
cairo_status_t status;
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
status = _cairo_surface_composite (operator,
&pattern.base,
NULL,
dst,
extents->x - clip->surface_rect.x,
extents->y - clip->surface_rect.y,
0, 0,
extents->x - dst_x,
extents->y - dst_y,
extents->width, extents->height);
_cairo_pattern_fini (&pattern.base);
return status;
}
static cairo_status_t
_cairo_clip_intersect_path (cairo_clip_t *clip,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_surface_t *target)
{
cairo_clip_path_t *clip_path;
cairo_status_t status;
if (clip->mode != CAIRO_CLIP_MODE_PATH)
return CAIRO_INT_STATUS_UNSUPPORTED;
clip_path = malloc (sizeof (cairo_clip_path_t));
if (clip_path == NULL)
return CAIRO_STATUS_NO_MEMORY;
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
if (status)
return status;
clip_path->ref_count = 1;
clip_path->fill_rule = fill_rule;
clip_path->tolerance = tolerance;
clip_path->antialias = antialias;
clip_path->prev = clip->path;
clip->path = clip_path;
clip->serial = _cairo_surface_allocate_clip_serial (target);
return CAIRO_STATUS_SUCCESS;
}
static cairo_clip_path_t *
_cairo_clip_path_reference (cairo_clip_path_t *clip_path)
{
if (clip_path == NULL)
return NULL;
clip_path->ref_count++;
return clip_path;
}
static void
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
{
if (clip_path == NULL)
return;
clip_path->ref_count--;
if (clip_path->ref_count)
return;
_cairo_path_fixed_fini (&clip_path->path);
_cairo_clip_path_destroy (clip_path->prev);
free (clip_path);
}
static cairo_status_t
_cairo_clip_intersect_region (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_surface_t *target)
{
pixman_region16_t *region;
cairo_status_t status;
if (clip->mode != CAIRO_CLIP_MODE_REGION)
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_traps_extract_region (traps, &region);
if (status)
return status;
if (region == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
status = CAIRO_STATUS_SUCCESS;
if (clip->region == NULL) {
clip->region = region;
} else {
pixman_region16_t *intersection = pixman_region_create();
if (pixman_region_intersect (intersection,
clip->region, region)
== PIXMAN_REGION_STATUS_SUCCESS) {
pixman_region_destroy (clip->region);
clip->region = intersection;
} else {
status = CAIRO_STATUS_NO_MEMORY;
}
pixman_region_destroy (region);
}
clip->serial = _cairo_surface_allocate_clip_serial (target);
return status;
}
static cairo_status_t
_cairo_clip_intersect_mask (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_antialias_t antialias,
cairo_surface_t *target)
{
cairo_pattern_union_t pattern;
cairo_box_t extents;
cairo_rectangle_t surface_rect;
cairo_surface_t *surface;
cairo_status_t status;
/* Represent the clip as a mask surface. We create a new surface
* the size of the intersection of the old mask surface and the
* extents of the new clip path. */
_cairo_traps_extents (traps, &extents);
_cairo_box_round_to_rectangle (&extents, &surface_rect);
if (clip->surface != NULL)
_cairo_rectangle_intersect (&surface_rect, &clip->surface_rect);
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
surface_rect.width,
surface_rect.height,
CAIRO_COLOR_WHITE);
if (surface->status)
return CAIRO_STATUS_NO_MEMORY;
/* Render the new clipping path into the new mask surface. */
_cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
&pattern.base,
surface,
antialias,
0, 0,
0, 0,
surface_rect.width,
surface_rect.height,
traps->traps,
traps->num_traps);
_cairo_pattern_fini (&pattern.base);
if (status) {
cairo_surface_destroy (surface);
return status;
}
/* If there was a clip surface already, combine it with the new
* mask surface using the IN operator, so we get the intersection
* of the old and new clipping paths. */
if (clip->surface != NULL) {
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
&pattern.base,
NULL,
surface,
surface_rect.x - clip->surface_rect.x,
surface_rect.y - clip->surface_rect.y,
0, 0,
0, 0,
surface_rect.width,
surface_rect.height);
_cairo_pattern_fini (&pattern.base);
if (status) {
cairo_surface_destroy (surface);
return status;
}
cairo_surface_destroy (clip->surface);
}
clip->surface = surface;
clip->surface_rect = surface_rect;
clip->serial = _cairo_surface_allocate_clip_serial (target);
return status;
}
cairo_status_t
_cairo_clip_clip (cairo_clip_t *clip,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_surface_t *target)
{
cairo_status_t status;
cairo_traps_t traps;
status = _cairo_clip_intersect_path (clip,
path, fill_rule, tolerance,
antialias, target);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
_cairo_traps_init (&traps);
status = _cairo_path_fixed_fill_to_traps (path,
fill_rule,
tolerance,
&traps);
if (status)
goto bail;
status = _cairo_clip_intersect_region (clip, &traps, target);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto bail;
status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
bail:
_cairo_traps_fini (&traps);
return status;
}

Просмотреть файл

@ -89,29 +89,19 @@ _cairo_color_init_rgb (cairo_color_t *color,
_cairo_color_init_rgba (color, red, green, blue, 1.0);
}
/* We multiply colors by (0x10000 - epsilon), such that we get a uniform
* range even for 0xffff. In other words, (1.0 - epsilon) would convert
* to 0xffff, not 0xfffe.
*/
#define CAIRO_COLOR_ONE_MINUS_EPSILON (65536.0 - 1e-5)
/* XXX: The calculation of:
channel * 0xffff
isn't really what we want since:
(1.0 - epsilon) * 0xffff = 0xfffe
In other words, given an input range of [0.0, 1.0], we have an
infinitely small range tha maps to the output value 0xffff,
(while having large, uniformly sized input ranges for all
other output values). This is undesirable, particularly when
we want to do optimizations for "opaque" colors specfied as
floating-point.
*/
static void
_cairo_color_compute_shorts (cairo_color_t *color)
{
color->red_short = color->red * color->alpha * 0xffff;
color->green_short = color->green * color->alpha * 0xffff;
color->blue_short = color->blue * color->alpha * 0xffff;
color->alpha_short = color->alpha * 0xffff;
color->red_short = color->red * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
color->green_short = color->green * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
color->blue_short = color->blue * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
color->alpha_short = color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
}
void

Просмотреть файл

@ -0,0 +1,73 @@
/* 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 D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
/**
* cairo_debug_reset_static_data:
*
* Resets all static data within cairo to its original state,
* (ie. identical to the state at the time of program invocation). For
* example, all caches within cairo will be flushed empty.
*
* This function is intended to be useful when using memory-checking
* tools such as valgrind. When valgrind's memcheck analyzes a
* cairo-using program without a call to cairo_debug_reset_static_data,
* it will report all data reachable via cairo's static objects as
* "still reachable". Calling cairo_debug_reset_static_data just prior
* to program termination will make it easier to get squeaky clean
* reports from valgrind.
*
* WARNING: It is only safe to call this function when there are no
* active cairo objects remaining, (ie. the appropriate destroy
* functions have been called as necessary). If there are active cairo
* objects, this call is likely to cause a crash, (eg. an assertion
* failure due to a hash table being destroyed when non-empty).
**/
void
cairo_debug_reset_static_data (void)
{
#if CAIRO_HAS_XLIB_SURFACE
_cairo_xlib_surface_reset_static_data ();
_cairo_xlib_screen_reset_static_data ();
#endif
_cairo_font_reset_static_data ();
#if CAIRO_HAS_FT_FONT
_cairo_ft_font_reset_static_data ();
#endif
}

Просмотреть файл

@ -0,0 +1,48 @@
/* 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 D. Worth <cworth@cworth.org>
*/
#ifndef CAIRO_DEBUG_H
#define CAIRO_DEBUG_H
#include <cairo-features.h>
CAIRO_BEGIN_DECLS
void
cairo_debug_reset_static_data (void);
CAIRO_END_DECLS
#endif /* CAIRO_H */

Просмотреть файл

@ -37,28 +37,40 @@
#ifndef CAIRO_FEATURES_H
#define CAIRO_FEATURES_H
#define @PS_SURFACE_FEATURE@
#ifdef __cplusplus
# define CAIRO_BEGIN_DECLS extern "C" {
# define CAIRO_END_DECLS }
#else
# define CAIRO_BEGIN_DECLS
# define CAIRO_END_DECLS
#endif
#define @PDF_SURFACE_FEATURE@
#define CAIRO_VERSION_MAJOR 0
#define CAIRO_VERSION_MINOR 9
#define CAIRO_VERSION_MICRO 1
#define @PNG_SURFACE_FEATURE@
#define CAIRO_VERSION_STRING "0.9.1"
#define @XLIB_SURFACE_FEATURE@
@PS_SURFACE_FEATURE@
#define @QUARTZ_SURFACE_FEATURE@
@PDF_SURFACE_FEATURE@
#define @XCB_SURFACE_FEATURE@
@XLIB_SURFACE_FEATURE@
#define @WIN32_SURFACE_FEATURE@
@QUARTZ_SURFACE_FEATURE@
#define @GLITZ_SURFACE_FEATURE@
@XCB_SURFACE_FEATURE@
#define @FT_FONT_FEATURE@
@WIN32_SURFACE_FEATURE@
#define @WIN32_FONT_FEATURE@
@GLITZ_SURFACE_FEATURE@
#define @ATSUI_FONT_FEATURE@
@FT_FONT_FEATURE@
#define @SANITY_CHECKING_FEATURE@
@WIN32_FONT_FEATURE@
@ATSUI_FONT_FEATURE@
@PNG_FUNCTIONS_FEATURE@
#endif

Просмотреть файл

@ -0,0 +1,352 @@
/* 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 University of Southern
* California.
*
* Contributor(s):
* Owen Taylor <otaylor@redhat.com>
*/
#include "cairoint.h"
static const cairo_font_options_t cairo_font_options_nil = {
CAIRO_ANTIALIAS_DEFAULT,
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_METRICS_DEFAULT
};
/**
* _cairo_font_options_init_default:
* @options: a #cairo_font_options_t
*
* Initializes all fileds of the font options object to default values.
**/
void
_cairo_font_options_init_default (cairo_font_options_t *options)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
}
/**
* cairo_font_options_create:
*
* Allocates a new font options object with all options initialized
* to default values.
*
* Return value: a newly allocated #cairo_font_options_t. Free with
* cairo_font_options_destroy(). This function always returns a
* valid pointer; if memory cannot be allocated, then a special
* error object is returned where all operations on the object do nothing.
* You can check for this with cairo_font_options_status().
**/
cairo_font_options_t *
cairo_font_options_create (void)
{
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
if (!options)
return (cairo_font_options_t *)&cairo_font_options_nil;
_cairo_font_options_init_default (options);
return options;
}
/**
* cairo_font_options_copy:
* @original: a #cairo_font_options_t
*
* Allocates a new font options object copying the option values from
* @original.
*
* Return value: a newly allocated #cairo_font_options_t. Free with
* cairo_font_options_destroy(). This function always returns a
* valid pointer; if memory cannot be allocated, then a special
* error object is returned where all operations on the object do nothing.
* You can check for this with cairo_font_options_status().
**/
cairo_font_options_t *
cairo_font_options_copy (const cairo_font_options_t *original)
{
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
if (!options)
return (cairo_font_options_t *)&cairo_font_options_nil;
*options = *original;
return options;
}
/**
* cairo_font_options_destroy:
* @options: a #cairo_font_options_t
*
* Destroys a #cairo_font_options_t object created with with
* cairo_font_options_create() or cairo_font_options_copy().
**/
void
cairo_font_options_destroy (cairo_font_options_t *options)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
free (options);
}
/**
* cairo_font_options_status:
* @options: a #cairo_font_options_t
*
* Checks whether an error has previously occurred for this
* font options object
*
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
**/
cairo_status_t
cairo_font_options_status (cairo_font_options_t *options)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return CAIRO_STATUS_NO_MEMORY;
else
return CAIRO_STATUS_SUCCESS;
}
/**
* cairo_font_options_merge:
* @options: a #cairo_font_options_t
* @other: another #cairo_font_options_t
*
* Merges non-default options from @other into @options, replacing
* existing values. This operation can be thought of as somewhat
* similar to compositing @other onto @options with the operation
* of %CAIRO_OPERATION_OVER.
**/
void
cairo_font_options_merge (cairo_font_options_t *options,
const cairo_font_options_t *other)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
options->antialias = other->antialias;
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
options->subpixel_order = other->subpixel_order;
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
options->hint_style = other->hint_style;
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
options->hint_metrics = other->hint_metrics;
}
/**
* cairo_font_options_equal:
* @options: a #cairo_font_options_t
* @other: another #cairo_font_options_t
*
* Compares two font options objects for equality.
*
* Return value: %TRUE if all fields of the two font options objects match
**/
cairo_bool_t
cairo_font_options_equal (const cairo_font_options_t *options,
const cairo_font_options_t *other)
{
return (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_hash:
* @options: a #cairo_font_options_t
*
* Compute a hash for the font options object; this value will
* be useful when storing an object containing a cairo_font_options_t
* in a hash table.
*
* Return value: the hash value for the font options object.
* The return value can be cast to a 32-bit type if a
* 32-bit hash value is needed.
**/
unsigned long
cairo_font_options_hash (const cairo_font_options_t *options)
{
return ((options->antialias) |
(options->subpixel_order << 4) |
(options->hint_style << 8) |
(options->hint_metrics << 16));
}
/**
* cairo_font_options_set_antialias:
* @options: a #cairo_font_options_t
* @antialias: the new antialiasing mode
*
* Sets the antiliasing mode for the font options object. This
* specifies the type of antialiasing to do when rendering text.
**/
void
cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->antialias = antialias;
}
/**
* cairo_font_options_get_antialias:
* @options: a #cairo_font_options_t
*
* Gets the antialising mode for the font options object.
*
* Return value: the antialiasing mode
**/
cairo_antialias_t
cairo_font_options_get_antialias (const cairo_font_options_t *options)
{
return options->antialias;
}
/**
* cairo_font_options_set_subpixel_order:
* @options: a #cairo_font_options_t
* @subpixel_order: the new subpixel order
*
* Sets the subpixel order for the font options object. The subpixel
* order specifies the order of color elements within each pixel on
* the display device when rendering with an antialiasing mode of
* %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
* #cairo_subpixel_order_t for full details.
**/
void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->subpixel_order = subpixel_order;
}
/**
* cairo_font_options_get_subpixel_order:
* @options: a #cairo_font_options_t
*
* Gets the subpixel order for the font options object.
* See the documentation for #cairo_subpixel_order_t for full details.
*
* Return value: the subpixel order for the font options object
**/
cairo_subpixel_order_t
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
{
return options->subpixel_order;
}
/**
* cairo_font_options_set_hint_style:
* @options: a #cairo_font_options_t
* @hint_style: the new hint style
*
* Sets the hint style for font outlines for the font options object.
* This controls whether to fit font outlines to the pixel grid,
* and if so, whether to optimize for fidelity or contrast.
* See the documentation for #cairo_hint_style_t for full details.
**/
void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->hint_style = hint_style;
}
/**
* cairo_font_options_get_hint_style:
* @options: a #cairo_font_options_t
*
* Gets the hint style for font outlines for the font options object.
* See the documentation for #cairo_hint_style_t for full details.
*
* Return value: the hint style for the font options object
**/
cairo_hint_style_t
cairo_font_options_get_hint_style (const cairo_font_options_t *options)
{
return options->hint_style;
}
/**
* cairo_font_options_set_hint_metrics:
* @options: a #cairo_font_options_t
* @hint_metrics: the new metrics hinting mode
*
* Sets the metrics hinting mode for the font options object. This
* controls whether metrics are quantized to integer values in
* device units.
* See the documentation for #cairo_hint_metrics_t for full details.
**/
void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics)
{
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->hint_metrics = hint_metrics;
}
/**
* cairo_font_options_get_hint_metrics:
* @options: a #cairo_font_options_t
*
* Gets the metrics hinting mode for the font options object.
* See the documentation for #cairo_hint_metrics_t for full details.
*
* Return value: the metrics hinting mode for the font options object
**/
cairo_hint_metrics_t
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
{
return options->hint_metrics;
}

Просмотреть файл

@ -0,0 +1,68 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 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):
* Kristian Høgsberg <krh@redhat.com>
*/
#include "cairoint.h"
#ifndef CAIRO_FONT_SUBSET_PRIVATE_H
#define CAIRO_FONT_SUBSET_PRIVATE_H
typedef struct cairo_font_subset_backend cairo_font_subset_backend_t;
typedef struct cairo_font_subset cairo_font_subset_t;
struct cairo_font_subset {
cairo_font_subset_backend_t *backend;
cairo_unscaled_font_t *unscaled_font;
unsigned int font_id;
char *base_font;
int num_glyphs;
int *widths;
long x_min, y_min, x_max, y_max;
long ascent, descent;
};
cairo_private int
_cairo_font_subset_use_glyph (cairo_font_subset_t *font, int glyph);
cairo_private cairo_status_t
_cairo_font_subset_generate (cairo_font_subset_t *font,
const char **data, unsigned long *length);
cairo_private void
_cairo_font_subset_destroy (cairo_font_subset_t *font);
cairo_private cairo_font_subset_t *
_cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font);
#endif /* CAIRO_FONT_SUBSET_PRIVATE_H */

Просмотреть файл

@ -0,0 +1,724 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 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):
* Kristian Høgsberg <krh@redhat.com>
*/
#include "cairoint.h"
#include "cairo-pdf.h"
/* XXX: Eventually, we need to handle other font backends */
#include "cairo-font-subset-private.h"
#include "cairo-ft-private.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_TABLES_H
typedef struct ft_subset_glyph ft_subset_glyph_t;
struct ft_subset_glyph {
int parent_index;
unsigned long location;
};
struct cairo_font_subset_backend {
int (*use_glyph) (void *abstract_font,
int glyph);
cairo_status_t (*generate) (void *abstract_font,
const char **data,
unsigned long *length);
void (*destroy) (void *abstract_font);
};
typedef struct cairo_pdf_ft_font cairo_pdf_ft_font_t;
struct cairo_pdf_ft_font {
cairo_font_subset_t base;
ft_subset_glyph_t *glyphs;
FT_Face face;
int checksum_index;
cairo_array_t output;
int *parent_to_subset;
cairo_status_t status;
};
static int
cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph);
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
#define SFNT_VERSION 0x00010000
#ifdef WORDS_BIGENDIAN
#define cpu_to_be16(v) (v)
#define be16_to_cpu(v) (v)
#define cpu_to_be32(v) (v)
#define be32_to_cpu(v) (v)
#else
static inline unsigned short
cpu_to_be16(unsigned short v)
{
return (v << 8) | (v >> 8);
}
static inline unsigned short
be16_to_cpu(unsigned short v)
{
return cpu_to_be16 (v);
}
static inline unsigned long
cpu_to_be32(unsigned long v)
{
return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
}
static inline unsigned long
be32_to_cpu(unsigned long v)
{
return cpu_to_be32 (v);
}
#endif
static cairo_font_subset_backend_t cairo_pdf_ft_font_backend;
int
_cairo_font_subset_use_glyph (cairo_font_subset_t *font, int glyph)
{
return font->backend->use_glyph (font, glyph);
}
cairo_status_t
_cairo_font_subset_generate (cairo_font_subset_t *font,
const char **data, unsigned long *length)
{
return font->backend->generate (font, data, length);
}
void
_cairo_font_subset_destroy (cairo_font_subset_t *font)
{
font->backend->destroy (font);
}
cairo_font_subset_t *
_cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font)
{
cairo_ft_unscaled_font_t *ft_unscaled_font;
FT_Face face;
cairo_pdf_ft_font_t *font;
unsigned long size;
int i, j;
/* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
if (! _cairo_unscaled_font_is_ft (unscaled_font))
return NULL;
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
/* We currently only support freetype truetype fonts. */
size = 0;
if (!FT_IS_SFNT (face) ||
FT_Load_Sfnt_Table (face, TTAG_glyf, 0, NULL, &size) != 0)
return NULL;
font = malloc (sizeof (cairo_pdf_ft_font_t));
if (font == NULL)
return NULL;
font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
font->base.backend = &cairo_pdf_ft_font_backend;
_cairo_array_init (&font->output, sizeof (char));
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
goto fail1;
font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));
if (font->glyphs == NULL)
goto fail2;
font->parent_to_subset = calloc (face->num_glyphs, sizeof (int));
if (font->parent_to_subset == NULL)
goto fail3;
font->base.num_glyphs = 1;
font->base.x_min = face->bbox.xMin;
font->base.y_min = face->bbox.yMin;
font->base.x_max = face->bbox.xMax;
font->base.y_max = face->bbox.yMax;
font->base.ascent = face->ascender;
font->base.descent = face->descender;
font->base.base_font = strdup (face->family_name);
if (font->base.base_font == NULL)
goto fail4;
for (i = 0, j = 0; font->base.base_font[j]; j++) {
if (font->base.base_font[j] == ' ')
continue;
font->base.base_font[i++] = font->base.base_font[j];
}
font->base.base_font[i] = '\0';
font->base.widths = calloc (face->num_glyphs, sizeof (int));
if (font->base.widths == NULL)
goto fail5;
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
font->status = CAIRO_STATUS_SUCCESS;
return &font->base;
fail5:
free (font->base.base_font);
fail4:
free (font->parent_to_subset);
fail3:
free (font->glyphs);
fail2:
_cairo_array_fini (&font->output);
fail1:
free (font);
return NULL;
}
static void
cairo_pdf_ft_font_destroy (void *abstract_font)
{
cairo_pdf_ft_font_t *font = abstract_font;
_cairo_unscaled_font_destroy (font->base.unscaled_font);
free (font->base.base_font);
free (font->parent_to_subset);
free (font->glyphs);
_cairo_array_fini (&font->output);
free (font);
}
static void *
cairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,
const void *data, size_t length)
{
void *p;
p = _cairo_array_append (&font->output, data, length);
if (p == NULL)
font->status = CAIRO_STATUS_NO_MEMORY;
return p;
}
static void
cairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,
unsigned short value)
{
unsigned short be16_value;
be16_value = cpu_to_be16 (value);
cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);
}
static void
cairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value)
{
unsigned long be32_value;
be32_value = cpu_to_be32 (value);
cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);
}
static unsigned long
cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
{
int length, aligned;
static const char pad[4];
length = _cairo_array_num_elements (&font->output);
aligned = (length + 3) & ~3;
cairo_pdf_ft_font_write (font, pad, aligned - length);
return aligned;
}
static int
cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
{
int i;
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 1);
cairo_pdf_ft_font_write_be16 (font, 1);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be32 (font, 12);
/* Output a format 6 encoding table. */
cairo_pdf_ft_font_write_be16 (font, 6);
cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);
for (i = 1; i < font->base.num_glyphs; i++)
cairo_pdf_ft_font_write_be16 (font, i);
return font->status;
}
static int
cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
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);
FT_Load_Sfnt_Table (font->face, tag, 0, buffer, &size);
return 0;
}
typedef struct composite_glyph composite_glyph_t;
struct composite_glyph {
unsigned short flags;
unsigned short index;
unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */
};
typedef struct glyph_data glyph_data_t;
struct glyph_data {
short num_contours;
char data[8];
composite_glyph_t glyph;
};
/* composite_glyph_t flags */
#define ARG_1_AND_2_ARE_WORDS 0x0001
#define WE_HAVE_A_SCALE 0x0008
#define MORE_COMPONENTS 0x0020
#define WE_HAVE_AN_X_AND_Y_SCALE 0x0040
#define WE_HAVE_A_TWO_BY_TWO 0x0080
static void
cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,
unsigned char *buffer)
{
glyph_data_t *glyph_data;
composite_glyph_t *composite_glyph;
int num_args;
int has_more_components;
unsigned short flags;
unsigned short index;
glyph_data = (glyph_data_t *) buffer;
if ((short)be16_to_cpu (glyph_data->num_contours) >= 0)
return;
composite_glyph = &glyph_data->glyph;
do {
flags = be16_to_cpu (composite_glyph->flags);
has_more_components = flags & MORE_COMPONENTS;
index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
composite_glyph->index = cpu_to_be16 (index);
num_args = 1;
if (flags & ARG_1_AND_2_ARE_WORDS)
num_args += 1;
if (flags & WE_HAVE_A_SCALE)
num_args += 1;
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
num_args += 2;
else if (flags & WE_HAVE_A_TWO_BY_TWO)
num_args += 3;
composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
} while (has_more_components);
}
static int
cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
unsigned long start_offset, index, size;
TT_Header *header;
unsigned long begin, end;
unsigned char *buffer;
int i;
union {
unsigned char *bytes;
unsigned short *short_offsets;
unsigned long *long_offsets;
} u;
header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
if (header->Index_To_Loc_Format == 0)
size = sizeof (short) * (font->face->num_glyphs + 1);
else
size = sizeof (long) * (font->face->num_glyphs + 1);
u.bytes = malloc (size);
if (u.bytes == NULL) {
font->status = CAIRO_STATUS_NO_MEMORY;
return font->status;
}
FT_Load_Sfnt_Table (font->face, TTAG_loca, 0, u.bytes, &size);
start_offset = _cairo_array_num_elements (&font->output);
for (i = 0; i < font->base.num_glyphs; i++) {
index = font->glyphs[i].parent_index;
if (header->Index_To_Loc_Format == 0) {
begin = be16_to_cpu (u.short_offsets[index]) * 2;
end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
}
else {
begin = be32_to_cpu (u.long_offsets[index]);
end = be32_to_cpu (u.long_offsets[index + 1]);
}
size = end - begin;
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)
break;
if (size != 0) {
FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
cairo_pdf_ft_font_remap_composite_glyph (font, buffer);
}
}
font->glyphs[i].location =
cairo_pdf_ft_font_align_output (font) - start_offset;
free (u.bytes);
return font->status;
}
static int
cairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
TT_Header *head;
head = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
cairo_pdf_ft_font_write_be32 (font, head->Table_Version);
cairo_pdf_ft_font_write_be32 (font, head->Font_Revision);
font->checksum_index = _cairo_array_num_elements (&font->output);
cairo_pdf_ft_font_write_be32 (font, 0);
cairo_pdf_ft_font_write_be32 (font, head->Magic_Number);
cairo_pdf_ft_font_write_be16 (font, head->Flags);
cairo_pdf_ft_font_write_be16 (font, head->Units_Per_EM);
cairo_pdf_ft_font_write_be32 (font, head->Created[0]);
cairo_pdf_ft_font_write_be32 (font, head->Created[1]);
cairo_pdf_ft_font_write_be32 (font, head->Modified[0]);
cairo_pdf_ft_font_write_be32 (font, head->Modified[1]);
cairo_pdf_ft_font_write_be16 (font, head->xMin);
cairo_pdf_ft_font_write_be16 (font, head->yMin);
cairo_pdf_ft_font_write_be16 (font, head->xMax);
cairo_pdf_ft_font_write_be16 (font, head->yMax);
cairo_pdf_ft_font_write_be16 (font, head->Mac_Style);
cairo_pdf_ft_font_write_be16 (font, head->Lowest_Rec_PPEM);
cairo_pdf_ft_font_write_be16 (font, head->Font_Direction);
cairo_pdf_ft_font_write_be16 (font, head->Index_To_Loc_Format);
cairo_pdf_ft_font_write_be16 (font, head->Glyph_Data_Format);
return font->status;
}
static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag)
{
TT_HoriHeader *hhea;
hhea = FT_Get_Sfnt_Table (font->face, ft_sfnt_hhea);
cairo_pdf_ft_font_write_be32 (font, hhea->Version);
cairo_pdf_ft_font_write_be16 (font, hhea->Ascender);
cairo_pdf_ft_font_write_be16 (font, hhea->Descender);
cairo_pdf_ft_font_write_be16 (font, hhea->Line_Gap);
cairo_pdf_ft_font_write_be16 (font, hhea->advance_Width_Max);
cairo_pdf_ft_font_write_be16 (font, hhea->min_Left_Side_Bearing);
cairo_pdf_ft_font_write_be16 (font, hhea->min_Right_Side_Bearing);
cairo_pdf_ft_font_write_be16 (font, hhea->xMax_Extent);
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Rise);
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Run);
cairo_pdf_ft_font_write_be16 (font, hhea->caret_Offset);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, 0);
cairo_pdf_ft_font_write_be16 (font, hhea->metric_Data_Format);
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
return font->status;
}
static int
cairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
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);
FT_Load_Sfnt_Table (font->face, TTAG_hmtx,
font->glyphs[i].parent_index * entry_size,
(FT_Byte *) p, &entry_size);
font->base.widths[i] = be16_to_cpu (p[0]);
}
return font->status;
}
static int
cairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
int i;
TT_Header *header;
header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);
if (header->Index_To_Loc_Format == 0) {
for (i = 0; i < font->base.num_glyphs + 1; i++)
cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);
}
else {
for (i = 0; i < font->base.num_glyphs + 1; i++)
cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);
}
return font->status;
}
static int
cairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
TT_MaxProfile *maxp;
maxp = FT_Get_Sfnt_Table (font->face, ft_sfnt_maxp);
cairo_pdf_ft_font_write_be32 (font, maxp->version);
cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);
cairo_pdf_ft_font_write_be16 (font, maxp->maxPoints);
cairo_pdf_ft_font_write_be16 (font, maxp->maxContours);
cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositePoints);
cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositeContours);
cairo_pdf_ft_font_write_be16 (font, maxp->maxZones);
cairo_pdf_ft_font_write_be16 (font, maxp->maxTwilightPoints);
cairo_pdf_ft_font_write_be16 (font, maxp->maxStorage);
cairo_pdf_ft_font_write_be16 (font, maxp->maxFunctionDefs);
cairo_pdf_ft_font_write_be16 (font, maxp->maxInstructionDefs);
cairo_pdf_ft_font_write_be16 (font, maxp->maxStackElements);
cairo_pdf_ft_font_write_be16 (font, maxp->maxSizeOfInstructions);
cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentElements);
cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentDepth);
return font->status;
}
typedef struct table table_t;
struct table {
unsigned long tag;
int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);
};
static const table_t truetype_tables[] = {
/* As we write out the glyf table we remap composite glyphs.
* Remapping composite glyphs will reference the sub glyphs the
* composite glyph is made up of. That needs to be done first so
* we have all the glyphs in the subset before going further. */
{ TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },
{ TTAG_cmap, cairo_pdf_ft_font_write_cmap_table },
{ TTAG_cvt, cairo_pdf_ft_font_write_generic_table },
{ TTAG_fpgm, cairo_pdf_ft_font_write_generic_table },
{ TTAG_head, cairo_pdf_ft_font_write_head_table },
{ TTAG_hhea, cairo_pdf_ft_font_write_hhea_table },
{ TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
{ TTAG_loca, cairo_pdf_ft_font_write_loca_table },
{ TTAG_maxp, cairo_pdf_ft_font_write_maxp_table },
{ TTAG_name, cairo_pdf_ft_font_write_generic_table },
{ TTAG_prep, cairo_pdf_ft_font_write_generic_table },
};
static cairo_status_t
cairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font)
{
unsigned short search_range, entry_selector, range_shift;
int num_tables;
num_tables = ARRAY_LENGTH (truetype_tables);
search_range = 1;
entry_selector = 0;
while (search_range * 2 <= num_tables) {
search_range *= 2;
entry_selector++;
}
search_range *= 16;
range_shift = num_tables * 16 - search_range;
cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);
cairo_pdf_ft_font_write_be16 (font, num_tables);
cairo_pdf_ft_font_write_be16 (font, search_range);
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);
return font->status;
}
static unsigned long
cairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,
unsigned long start, unsigned long end)
{
unsigned long *padded_end;
unsigned long *p;
unsigned long checksum;
char *data;
checksum = 0;
data = _cairo_array_index (&font->output, 0);
p = (unsigned long *) (data + start);
padded_end = (unsigned long *) (data + ((end + 3) & ~3));
while (p < padded_end)
checksum += *p++;
return checksum;
}
static void
cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,
unsigned long start, unsigned long end)
{
unsigned long *entry;
entry = _cairo_array_index (&font->output, 12 + 16 * index);
entry[0] = cpu_to_be32 (tag);
entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));
entry[2] = cpu_to_be32 (start);
entry[3] = cpu_to_be32 (end - start);
}
static cairo_status_t
cairo_pdf_ft_font_generate (void *abstract_font,
const char **data, unsigned long *length)
{
cairo_ft_unscaled_font_t *ft_unscaled_font;
cairo_pdf_ft_font_t *font = abstract_font;
unsigned long start, end, next, checksum, *checksum_location;
int i;
/* XXX: It would be cleaner to do something besides this cast
* here. Perhaps cairo_pdf_ft_font_t should just have the
* cairo_ft_unscaled_font_t rather than having the generic
* cairo_unscaled_font_t in the base class? */
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
if (cairo_pdf_ft_font_write_offset_table (font))
goto fail;
start = cairo_pdf_ft_font_align_output (font);
end = start;
end = 0;
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
if (truetype_tables[i].write (font, truetype_tables[i].tag))
goto fail;
end = _cairo_array_num_elements (&font->output);
next = cairo_pdf_ft_font_align_output (font);
cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
start, end);
start = next;
}
checksum =
0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);
checksum_location = _cairo_array_index (&font->output, font->checksum_index);
*checksum_location = cpu_to_be32 (checksum);
*data = _cairo_array_index (&font->output, 0);
*length = _cairo_array_num_elements (&font->output);
fail:
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
font->face = NULL;
return font->status;
}
static int
cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph)
{
cairo_pdf_ft_font_t *font = abstract_font;
if (font->parent_to_subset[glyph] == 0) {
font->parent_to_subset[glyph] = font->base.num_glyphs;
font->glyphs[font->base.num_glyphs].parent_index = glyph;
font->base.num_glyphs++;
}
return font->parent_to_subset[glyph];
}
static cairo_font_subset_backend_t cairo_pdf_ft_font_backend = {
cairo_pdf_ft_font_use_glyph,
cairo_pdf_ft_font_generate,
cairo_pdf_ft_font_destroy
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -40,10 +40,18 @@
#include <cairo-ft.h>
#include <cairoint.h>
#ifdef CAIRO_HAS_FT_FONT
#if CAIRO_HAS_FT_FONT
CAIRO_BEGIN_DECLS
typedef struct _cairo_ft_unscaled_font cairo_ft_unscaled_font_t;
cairo_private cairo_bool_t
_cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font);
cairo_private cairo_bool_t
_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font);
/* These functions are needed by the PDF backend, which needs to keep track of the
* the different fonts-on-disk used by a document, so it can embed them
*/
@ -51,10 +59,10 @@ cairo_private cairo_unscaled_font_t *
_cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *scaled_font);
cairo_private FT_Face
_cairo_ft_unscaled_font_lock_face (cairo_unscaled_font_t *unscaled_font);
_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
cairo_private void
_cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font);
_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
CAIRO_END_DECLS

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_FT_FONT
#if CAIRO_HAS_FT_FONT
/* Fontconfig/Freetype platform-specific font interface */
@ -52,6 +52,10 @@ CAIRO_BEGIN_DECLS
cairo_font_face_t *
cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
void
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
FcPattern *pattern);
cairo_font_face_t *
cairo_ft_font_face_create_for_ft_face (FT_Face face,
int load_flags);

Просмотреть файл

@ -52,27 +52,26 @@ _cairo_glitz_surface_finish (void *abstract_surface)
}
static glitz_format_name_t
_glitz_format (cairo_format_t format)
_glitz_format_from_content (cairo_content_t content)
{
switch (format) {
default:
case CAIRO_FORMAT_ARGB32:
return GLITZ_STANDARD_ARGB32;
case CAIRO_FORMAT_RGB24:
switch (content) {
case CAIRO_CONTENT_COLOR:
return GLITZ_STANDARD_RGB24;
case CAIRO_FORMAT_A8:
case CAIRO_CONTENT_ALPHA:
return GLITZ_STANDARD_A8;
case CAIRO_FORMAT_A1:
return GLITZ_STANDARD_A1;
case CAIRO_CONTENT_COLOR_ALPHA:
return GLITZ_STANDARD_ARGB32;
}
ASSERT_NOT_REACHED;
return GLITZ_STANDARD_ARGB32;
}
static cairo_surface_t *
_cairo_glitz_surface_create_similar (void *abstract_src,
cairo_format_t format,
int draw,
int width,
int height)
cairo_content_t content,
int width,
int height)
{
cairo_glitz_surface_t *src = abstract_src;
cairo_surface_t *crsurface;
@ -82,13 +81,18 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
drawable = glitz_surface_get_drawable (src->surface);
gformat = glitz_find_standard_format (drawable, _glitz_format (format));
if (!gformat)
return NULL;
gformat = glitz_find_standard_format (drawable,
_glitz_format_from_content (content));
if (!gformat) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = glitz_surface_create (drawable, gformat, width, height, 0, NULL);
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
crsurface = cairo_glitz_surface_create (surface);
@ -206,8 +210,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
&format,
width, height,
pf.bytes_per_line);
if (!image)
if (image->base.status)
{
free (pixels);
return CAIRO_STATUS_NO_MEMORY;
@ -215,9 +218,6 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
_cairo_image_surface_assume_ownership_of_data (image);
_cairo_image_surface_set_repeat (image, surface->base.repeat);
_cairo_image_surface_set_matrix (image, &(surface->base.matrix));
*image_out = image;
return CAIRO_STATUS_SUCCESS;
@ -344,22 +344,25 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
cairo_glitz_surface_t *surface = abstract_surface;
cairo_glitz_surface_t *clone;
if (surface->base.status)
return surface->base.status;
if (src->backend == surface->base.backend)
{
*clone_out = src;
cairo_surface_reference (src);
*clone_out = 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;
cairo_content_t content = _cairo_content_from_format (image_src->format);
clone = (cairo_glitz_surface_t *)
_cairo_glitz_surface_create_similar (surface, image_src->format, 0,
_cairo_glitz_surface_create_similar (surface, content,
image_src->width,
image_src->height);
if (!clone)
if (clone->base.status)
return CAIRO_STATUS_NO_MEMORY;
_cairo_glitz_surface_set_image (clone, image_src, 0, 0);
@ -444,73 +447,18 @@ _glitz_operator (cairo_operator_t op)
return CAIRO_OPERATOR_XOR;
}
#define CAIRO_GLITZ_FEATURE_OK(surface, name) \
(glitz_drawable_get_features (glitz_surface_get_drawable (surface)) & \
(GLITZ_FEATURE_ ## name ## _MASK))
static glitz_status_t
_glitz_ensure_target (glitz_surface_t *surface)
{
glitz_drawable_t *drawable;
if (glitz_surface_get_attached_drawable (surface) ||
CAIRO_GLITZ_FEATURE_OK (surface, FRAMEBUFFER_OBJECT))
return CAIRO_STATUS_SUCCESS;
drawable = glitz_surface_get_attached_drawable (surface);
if (!drawable) {
glitz_drawable_format_t *dformat;
glitz_drawable_format_t templ;
glitz_format_t *format;
glitz_drawable_t *pbuffer;
unsigned long mask;
int i;
format = glitz_surface_get_format (surface);
if (format->type != GLITZ_FORMAT_TYPE_COLOR)
return CAIRO_INT_STATUS_UNSUPPORTED;
drawable = glitz_surface_get_drawable (surface);
dformat = glitz_drawable_get_format (drawable);
templ.types.pbuffer = 1;
mask = GLITZ_FORMAT_PBUFFER_MASK;
templ.samples = dformat->samples;
mask |= GLITZ_FORMAT_SAMPLES_MASK;
i = 0;
do {
dformat = glitz_find_similar_drawable_format (drawable,
mask, &templ, i++);
if (dformat) {
int sufficient = 1;
if (format->color.red_size) {
if (dformat->color.red_size < format->color.red_size)
sufficient = 0;
}
if (format->color.alpha_size) {
if (dformat->color.alpha_size < format->color.alpha_size)
sufficient = 0;
}
if (sufficient)
break;
}
} while (dformat);
if (!dformat)
return CAIRO_INT_STATUS_UNSUPPORTED;
pbuffer =
glitz_create_pbuffer_drawable (drawable, dformat,
glitz_surface_get_width (surface),
glitz_surface_get_height (surface));
if (!pbuffer)
return CAIRO_INT_STATUS_UNSUPPORTED;
glitz_surface_attach (surface, pbuffer,
GLITZ_DRAWABLE_BUFFER_FRONT_COLOR,
0, 0);
glitz_drawable_destroy (pbuffer);
}
return CAIRO_STATUS_SUCCESS;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
typedef struct _cairo_glitz_surface_attributes {
@ -540,13 +488,26 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
switch (pattern->type) {
case CAIRO_PATTERN_LINEAR:
case CAIRO_PATTERN_RADIAL: {
cairo_gradient_pattern_t *gradient =
cairo_gradient_pattern_t *gradient =
(cairo_gradient_pattern_t *) pattern;
glitz_drawable_t *drawable;
glitz_fixed16_16_t *params;
int n_params;
int i;
unsigned short alpha;
char *data;
glitz_fixed16_16_t *params;
int n_params;
unsigned int *pixels;
int i;
unsigned char alpha;
glitz_buffer_t *buffer;
static glitz_pixel_format_t format = {
{
32,
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff
},
0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
};
/* XXX: the current color gradient acceleration provided by glitz is
* experimental, it's been proven inappropriate in a number of ways,
@ -569,22 +530,20 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
break;
}
drawable = glitz_surface_get_drawable (dst->surface);
if (!(glitz_drawable_get_features (drawable) &
GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK))
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;
alpha = (gradient->stops[0].color.alpha) * 0xffff;
alpha = gradient->stops[0].color.alpha * 0xff;
for (i = 1; i < gradient->n_stops; i++)
{
unsigned short a;
unsigned char a;
a = (gradient->stops[i].color.alpha) * 0xffff;
a = gradient->stops[i].color.alpha * 0xff;
if (a != alpha)
break;
}
@ -596,35 +555,51 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
n_params = gradient->n_stops * 3 + 4;
params = malloc (sizeof (glitz_fixed16_16_t) * n_params);
if (!params)
data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
sizeof (unsigned int) * gradient->n_stops);
if (!data)
return CAIRO_STATUS_NO_MEMORY;
src = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_FORMAT_ARGB32, 0,
gradient->n_stops, 1);
if (!src)
params = (glitz_fixed16_16_t *) data;
pixels = (unsigned int *)
(data + sizeof (glitz_fixed16_16_t) * n_params);
buffer = glitz_buffer_create_for_data (pixels);
if (!buffer)
{
free (params);
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
for (i = 0; i < gradient->n_stops; i++) {
glitz_color_t color;
color.red = gradient->stops[i].color.red * alpha;
color.green = gradient->stops[i].color.green * alpha;
color.blue = gradient->stops[i].color.blue * alpha;
color.alpha = alpha;
glitz_set_rectangle (src->surface, &color, i, 0, 1, 1);
src = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_COLOR_ALPHA,
gradient->n_stops, 1);
if (src->base.status)
{
glitz_buffer_destroy (buffer);
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
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));
params[4 + 3 * i] = gradient->stops[i].offset;
params[5 + 3 * i] = i << 16;
params[6 + 3 * i] = 0;
}
glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
&format, buffer);
glitz_buffer_destroy (buffer);
if (pattern->type == CAIRO_PATTERN_LINEAR)
{
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
@ -718,13 +693,12 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
}
static void
_cairo_glitz_pattern_release_surface (cairo_glitz_surface_t *dst,
_cairo_glitz_pattern_release_surface (cairo_pattern_t *pattern,
cairo_glitz_surface_t *surface,
cairo_glitz_surface_attributes_t *attr)
{
if (attr->acquired)
_cairo_pattern_release_surface (&dst->base, &surface->base,
&attr->base);
_cairo_pattern_release_surface (pattern, &surface->base, &attr->base);
else
cairo_surface_destroy (&surface->base);
}
@ -790,13 +764,12 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
width, height,
mask_out, mattr);
if (status)
_cairo_glitz_pattern_release_surface (&tmp.base, *src_out, sattr);
_cairo_pattern_fini (&tmp.base);
if (status)
{
_cairo_glitz_pattern_release_surface (dst, *src_out, sattr);
return status;
}
return status;
}
else
{
@ -870,7 +843,7 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
if (mask_attr.n_params)
free (mask_attr.params);
_cairo_glitz_pattern_release_surface (dst, mask, &mask_attr);
_cairo_glitz_pattern_release_surface (mask_pattern, mask, &mask_attr);
}
else
{
@ -888,7 +861,7 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
if (src_attr.n_params)
free (src_attr.params);
_cairo_glitz_pattern_release_surface (dst, src, &src_attr);
_cairo_glitz_pattern_release_surface (src_pattern, src, &src_attr);
if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -914,10 +887,6 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
glitz_color.blue = color->blue_short;
glitz_color.alpha = color->alpha_short;
if (glitz_surface_get_width (dst->surface) != 1 ||
glitz_surface_get_height (dst->surface) != 1)
_glitz_ensure_target (dst->surface);
glitz_set_rectangles (dst->surface, &glitz_color,
(glitz_rectangle_t *) rects, n_rects);
}
@ -933,9 +902,10 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
src = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_solid (&dst->base,
CAIRO_FORMAT_ARGB32, 1, 1,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
(cairo_color_t *) color);
if (!src)
if (src->base.status)
return CAIRO_STATUS_NO_MEMORY;
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
@ -966,6 +936,7 @@ static cairo_int_status_t
_cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
int src_y,
int dst_x,
@ -975,6 +946,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
cairo_trapezoid_t *traps,
int n_traps)
{
cairo_pattern_union_t tmp_src_pattern;
cairo_pattern_t *src_pattern;
cairo_glitz_surface_attributes_t attributes;
cairo_glitz_surface_t *dst = abstract_dst;
cairo_glitz_surface_t *src;
@ -984,6 +957,9 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
cairo_int_status_t status;
unsigned short alpha;
if (dst->base.status)
return dst->base.status;
if (op == CAIRO_OPERATOR_SATURATE)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -992,16 +968,13 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
if (pattern->type == CAIRO_PATTERN_SURFACE)
{
cairo_pattern_union_t tmp;
_cairo_pattern_init_copy (&tmp.base, pattern);
_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base, dst,
src_x, src_y,
width, height,
&src, &attributes);
_cairo_pattern_fini (&tmp.base);
src_pattern = &tmp_src_pattern.base;
}
else
{
@ -1009,6 +982,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
src_x, src_y,
width, height,
&src, &attributes);
src_pattern = pattern;
}
alpha = 0xffff;
@ -1035,12 +1009,15 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
mask = (cairo_glitz_surface_t *)
_cairo_glitz_surface_create_similar (&dst->base,
CAIRO_FORMAT_A8, 0,
CAIRO_CONTENT_ALPHA,
2, 1);
if (!mask)
if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
return CAIRO_STATUS_NO_MEMORY;
}
color.red = color.green = color.blue = color.alpha = 0xffff;
@ -1063,8 +1040,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
data = realloc (data, data_size);
if (!data)
{
_cairo_glitz_pattern_release_surface (dst, src,
_cairo_glitz_pattern_release_surface (src_pattern, src,
&attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
return CAIRO_STATUS_NO_MEMORY;
}
@ -1074,8 +1053,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
buffer = glitz_buffer_create_for_data (data);
if (!buffer) {
free (data);
_cairo_glitz_pattern_release_surface (dst, src,
_cairo_glitz_pattern_release_surface (src_pattern, src,
&attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
return CAIRO_STATUS_NO_MEMORY;
}
}
@ -1109,7 +1090,9 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
data = malloc (stride * height);
if (!data)
{
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
return CAIRO_STATUS_NO_MEMORY;
}
@ -1123,7 +1106,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
CAIRO_FORMAT_A8,
width, height,
-stride);
if (!image)
if (image->base.status)
{
cairo_surface_destroy (&src->base);
free (data);
@ -1135,11 +1118,11 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
mask = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_FORMAT_A8, 0,
CAIRO_CONTENT_ALPHA,
width, height);
if (!mask)
if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
free (data);
cairo_surface_destroy (&image->base);
return CAIRO_STATUS_NO_MEMORY;
@ -1172,7 +1155,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
free (data);
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
if (mask)
cairo_surface_destroy (&mask->base);
@ -1289,10 +1275,13 @@ _cairo_glitz_area_move_in (cairo_glitz_area_t *area,
static void
_cairo_glitz_area_move_out (cairo_glitz_area_t *area)
{
(*area->root->funcs->move_out) (area, area->closure);
if (area->root)
{
(*area->root->funcs->move_out) (area, area->closure);
area->closure = NULL;
area->state = CAIRO_GLITZ_AREA_AVAILABLE;
area->closure = NULL;
area->state = CAIRO_GLITZ_AREA_AVAILABLE;
}
}
static cairo_glitz_area_t *
@ -1328,7 +1317,7 @@ _cairo_glitz_area_create (cairo_glitz_root_area_t *root,
static void
_cairo_glitz_area_destroy (cairo_glitz_area_t *area)
{
if (!area)
if (area == NULL)
return;
if (area->state == CAIRO_GLITZ_AREA_OCCUPIED)
@ -1390,6 +1379,8 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
cairo_bool_t kick_out,
void *closure)
{
cairo_status_t status;
if (area->width < width || area->height < height)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1403,8 +1394,9 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
return CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_glitz_area_move_out (area);
} else
} else {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* fall-through */
case CAIRO_GLITZ_AREA_AVAILABLE: {
@ -1449,10 +1441,11 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
area->state = CAIRO_GLITZ_AREA_DIVIDED;
if (CAIRO_OK (_cairo_glitz_area_find (area->area[0],
width, height,
kick_out, closure)))
return CAIRO_STATUS_SUCCESS;
status = _cairo_glitz_area_find (area->area[0],
width, height,
kick_out, closure);
if (status == CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_SUCCESS;
}
} break;
case CAIRO_GLITZ_AREA_DIVIDED: {
@ -1466,9 +1459,10 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
if (area->area[i]->width >= width &&
area->area[i]->height >= height)
{
if (CAIRO_OK (_cairo_glitz_area_find (area->area[i],
width, height,
kick_out, closure)))
status = _cairo_glitz_area_find (area->area[i],
width, height,
kick_out, closure);
if (status == CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_SUCCESS;
rejected = TRUE;
@ -1488,8 +1482,9 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
to_area->closure,
closure) >= 0)
return CAIRO_INT_STATUS_UNSUPPORTED;
} else
} else {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
}
for (i = 0; i < 4; i++)
@ -1500,8 +1495,10 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area,
area->closure = NULL;
area->state = CAIRO_GLITZ_AREA_AVAILABLE;
if (CAIRO_OK (_cairo_glitz_area_find (area, width, height,
TRUE, closure)))
status = _cairo_glitz_area_find (area, width, height,
TRUE, closure);
if (status == CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_SUCCESS;
} break;
@ -1560,7 +1557,7 @@ typedef struct _cairo_glitz_glyph_cache {
typedef struct {
cairo_glyph_cache_key_t key;
int refcount;
int ref_count;
cairo_glyph_size_t size;
cairo_glitz_area_t *area;
cairo_bool_t locked;
@ -1607,20 +1604,48 @@ static const cairo_glitz_area_funcs_t _cairo_glitz_area_funcs = {
};
static cairo_status_t
_cairo_glitz_glyph_cache_entry_create (void *abstract_cache,
_cairo_glitz_glyph_cache_create_entry (void *abstract_cache,
void *abstract_key,
void **return_entry)
{
cairo_glitz_glyph_cache_entry_t *entry;
cairo_glyph_cache_key_t *key = abstract_key;
cairo_status_t status;
cairo_cache_t *im_cache;
cairo_image_glyph_cache_entry_t *im;
unsigned long entry_memory = 0;
entry = malloc (sizeof (cairo_glitz_glyph_cache_entry_t));
if (!entry)
return CAIRO_STATUS_NO_MEMORY;
entry->refcount = 1;
_cairo_lock_global_image_glyph_cache ();
im_cache = _cairo_get_global_image_glyph_cache ();
if (im_cache == NULL) {
_cairo_unlock_global_image_glyph_cache ();
free (entry);
return CAIRO_STATUS_NO_MEMORY;
}
status = _cairo_cache_lookup (im_cache, key, (void **) (&im), NULL);
if (status != CAIRO_STATUS_SUCCESS || im == NULL) {
_cairo_unlock_global_image_glyph_cache ();
free (entry);
return CAIRO_STATUS_NO_MEMORY;
}
if (im->image)
entry_memory = im->image->width * im->image->stride;
_cairo_unlock_global_image_glyph_cache ();
entry->ref_count = 1;
entry->key = *key;
entry->area = NULL;
entry->key.base.memory = entry_memory;
entry->area = NULL;
entry->locked = FALSE;
_cairo_unscaled_font_reference (entry->key.unscaled);
@ -1631,13 +1656,13 @@ _cairo_glitz_glyph_cache_entry_create (void *abstract_cache,
}
static void
_cairo_glitz_glyph_cache_entry_destroy (void *abstract_cache,
_cairo_glitz_glyph_cache_destroy_entry (void *abstract_cache,
void *abstract_entry)
{
cairo_glitz_glyph_cache_entry_t *entry = abstract_entry;
entry->refcount--;
if (entry->refcount)
entry->ref_count--;
if (entry->ref_count)
return;
if (entry->area)
@ -1653,11 +1678,11 @@ _cairo_glitz_glyph_cache_entry_reference (void *abstract_entry)
{
cairo_glitz_glyph_cache_entry_t *entry = abstract_entry;
entry->refcount++;
entry->ref_count++;
}
static void
_cairo_glitz_glyph_cache_destroy (void *abstract_cache)
_cairo_glitz_glyph_cache_destroy_cache (void *abstract_cache)
{
cairo_glitz_glyph_cache_t *cache = abstract_cache;
@ -1669,9 +1694,9 @@ _cairo_glitz_glyph_cache_destroy (void *abstract_cache)
static const cairo_cache_backend_t _cairo_glitz_glyph_cache_backend = {
_cairo_glyph_cache_hash,
_cairo_glyph_cache_keys_equal,
_cairo_glitz_glyph_cache_entry_create,
_cairo_glitz_glyph_cache_entry_destroy,
_cairo_glitz_glyph_cache_destroy
_cairo_glitz_glyph_cache_create_entry,
_cairo_glitz_glyph_cache_destroy_entry,
_cairo_glitz_glyph_cache_destroy_cache
};
static cairo_glitz_glyph_cache_t *_cairo_glitz_glyph_caches = NULL;
@ -1706,7 +1731,7 @@ _cairo_glitz_get_glyph_cache (cairo_glitz_surface_t *surface)
GLYPH_CACHE_TEXTURE_SIZE,
GLYPH_CACHE_TEXTURE_SIZE,
0, NULL);
if (!cache->surface)
if (cache->surface == NULL)
{
free (cache);
return NULL;
@ -1757,7 +1782,8 @@ _cairo_glitz_cache_glyph (cairo_glitz_glyph_cache_t *cache,
entry->size.height > GLYPH_CACHE_MAX_HEIGHT)
return CAIRO_STATUS_SUCCESS;
if (!image_entry->image)
if ((entry->size.width == 0 && entry->size.height == 0) ||
!image_entry->image)
{
entry->area = &_empty_area;
return CAIRO_STATUS_SUCCESS;
@ -1910,7 +1936,9 @@ _cairo_glitz_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
goto UNLOCK;
}
_cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
if (status)
goto UNLOCK;
for (i = 0; i < num_glyphs; i++)
{
@ -2088,7 +2116,7 @@ UNLOCK:
}
for (i = 0; i < num_glyphs; i++)
_cairo_glitz_glyph_cache_entry_destroy (cache, entries[i]);
_cairo_glitz_glyph_cache_destroy_entry (cache, entries[i]);
glitz_buffer_destroy (buffer);
@ -2100,7 +2128,7 @@ UNLOCK:
if (attributes.n_params)
free (attributes.params);
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
_cairo_glitz_pattern_release_surface (pattern, src, &attributes);
if (status)
return status;
@ -2125,8 +2153,13 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
NULL, /* copy_page */
NULL, /* show_page */
_cairo_glitz_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_glitz_surface_get_extents,
_cairo_glitz_surface_show_glyphs
_cairo_glitz_surface_show_glyphs,
NULL, /* fill_path */
NULL, /* get_font_options */
NULL, /* flush */
NULL /* mark_dirty_rectangle */
};
cairo_surface_t *
@ -2134,12 +2167,14 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
{
cairo_glitz_surface_t *crsurface;
if (!surface)
return NULL;
if (surface == NULL)
return (cairo_surface_t*) &_cairo_surface_nil;
crsurface = malloc (sizeof (cairo_glitz_surface_t));
if (crsurface == NULL)
return NULL;
if (crsurface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend);

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_GLITZ_SURFACE
#if CAIRO_HAS_GLITZ_SURFACE
#include <glitz.h>

Просмотреть файл

@ -36,10 +36,13 @@
#ifndef CAIRO_GSTATE_PRIVATE_H
#define CAIRO_GSTATE_PRIVATE_H
#include "cairo-clip-private.h"
struct _cairo_gstate {
cairo_operator_t operator;
double tolerance;
cairo_antialias_t antialias;
/* stroke style */
double line_width;
@ -52,30 +55,24 @@ struct _cairo_gstate {
double *dash;
int num_dashes;
double dash_offset;
double max_dash_length;
double fraction_dash_lit;
char *font_family; /* NULL means CAIRO_FONT_FAMILY_DEFAULT; */
cairo_font_slant_t font_slant;
cairo_font_weight_t font_weight;
cairo_font_face_t *font_face;
cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */
cairo_surface_t *surface;
int surface_level; /* Used to detect bad nested use */
cairo_pattern_t *source;
cairo_clip_rec_t clip;
cairo_matrix_t font_matrix;
cairo_font_options_t font_options;
cairo_clip_t clip;
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_surface_t *target;
cairo_pattern_t *source;
struct _cairo_gstate *next;
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,125 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc.
* 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):
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#ifndef CAIRO_HASH_PRIVATE_H
#define CAIRO_HASH_PRIVATE_H
/* XXX: I'd like this file to be self-contained in terms of
* includeability, but that's not really possible with the current
* monolithic cairoint.h. So, for now, just include cairoint.h instead
* if you want to include this file. */
typedef struct _cairo_hash_table cairo_hash_table_t;
/**
* cairo_hash_entry_t:
*
* A #cairo_hash_entry_t contains both a key and a value for
* cairo_hash_table_t. User-derived types for cairo_hash_entry_t must
* be type-compatible with this structure (eg. they must have an
* unsigned long as the first parameter. The easiest way to get this
* is to use:
*
* typedef _my_entry {
* cairo_hash_entry_t base;
* ... Remainder of key and value fields here ..
* } my_entry_t;
*
* which then allows a pointer to my_entry_t to be passed to any of
* the cairo_hash_table functions as follows without requiring a cast:
*
* _cairo_hash_table_insert (hash_table, &my_entry->base);
*
* IMPORTANT: The caller is reponsible for initializing
* my_entry->base.hash with a hash code derived from the key. The
* essential property of the hash code is that keys_equal must never
* return TRUE for two keys that have different hashes. The best hash
* code will reduce the frequency of two keys with the same code for
* which keys_equal returns FALSE.
*
* Which parts of the entry make up the "key" and which part make up
* the value are entirely up to the caller, (as determined by the
* computation going into base.hash as well as the keys_equal
* function). A few of the cairo_hash_table functions accept an entry
* which will be used exclusively as a "key", (indicated by a
* parameter name of key). In these cases, the value-related fields of
* the entry need not be initialized if so desired.
**/
typedef struct _cairo_hash_entry {
unsigned long hash;
} cairo_hash_entry_t;
typedef cairo_bool_t
(*cairo_hash_keys_equal_func_t) (void *key_a, void *key_b);
typedef cairo_bool_t
(*cairo_hash_predicate_func_t) (void *entry);
typedef void
(*cairo_hash_callback_func_t) (void *entry,
void *closure);
cairo_private cairo_hash_table_t *
_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal);
cairo_private void
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table);
cairo_private cairo_bool_t
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key,
cairo_hash_entry_t **entry_return);
cairo_private void *
_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
cairo_hash_predicate_func_t predicate);
cairo_private cairo_status_t
_cairo_hash_table_insert (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *entry);
cairo_private void
_cairo_hash_table_remove (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key);
cairo_private void
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
cairo_hash_callback_func_t hash_callback,
void *closure);
#endif

Просмотреть файл

@ -0,0 +1,533 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc.
* 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):
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#include "cairoint.h"
/*
* An entry can be in one of three states:
*
* FREE: Entry has never been used, terminates all searches.
* Appears in the table as a NULL pointer.
*
* DEAD: Entry had been live in the past. A dead entry can be reused
* but does not terminate a search for an exact entry.
* Appears in the table as a pointer to DEAD_ENTRY.
*
* LIVE: Entry is currently being used.
* Appears in the table as any non-NULL, non-DEAD_ENTRY pointer.
*/
static cairo_hash_entry_t dead_entry = { 0 };
#define DEAD_ENTRY (&dead_entry)
#define ENTRY_IS_FREE(entry) ((entry) == NULL)
#define ENTRY_IS_DEAD(entry) ((entry) == DEAD_ENTRY)
#define ENTRY_IS_LIVE(entry) ((entry) && ! ENTRY_IS_DEAD(entry))
/* We expect keys will not be destroyed frequently, so our table does not
* contain any explicit shrinking code nor any chain-coalescing code for
* entries randomly deleted by memory pressure (except during rehashing, of
* course). These assumptions are potentially bad, but they make the
* implementation straightforward.
*
* Revisit later if evidence appears that we're using excessive memory from
* a mostly-dead table.
*
* This table is open-addressed with double hashing. Each table size is a
* prime chosen to be a little more than double the high water mark for a
* given arrangement, so the tables should remain < 50% full. The table
* size makes for the "first" hash modulus; a second prime (2 less than the
* first prime) serves as the "second" hash modulus, which is co-prime and
* thus guarantees a complete permutation of table indices.
*
* This structure, and accompanying table, is borrowed/modified from the
* file xserver/render/glyph.c in the freedesktop.org x server, with
* permission (and suggested modification of doubling sizes) by Keith
* Packard.
*/
typedef struct _cairo_hash_table_arrangement {
unsigned long high_water_mark;
unsigned long size;
unsigned long rehash;
} cairo_hash_table_arrangement_t;
static const cairo_hash_table_arrangement_t hash_table_arrangements [] = {
{ 16, 43, 41 },
{ 32, 73, 71 },
{ 64, 151, 149 },
{ 128, 283, 281 },
{ 256, 571, 569 },
{ 512, 1153, 1151 },
{ 1024, 2269, 2267 },
{ 2048, 4519, 4517 },
{ 4096, 9013, 9011 },
{ 8192, 18043, 18041 },
{ 16384, 36109, 36107 },
{ 32768, 72091, 72089 },
{ 65536, 144409, 144407 },
{ 131072, 288361, 288359 },
{ 262144, 576883, 576881 },
{ 524288, 1153459, 1153457 },
{ 1048576, 2307163, 2307161 },
{ 2097152, 4613893, 4613891 },
{ 4194304, 9227641, 9227639 },
{ 8388608, 18455029, 18455027 },
{ 16777216, 36911011, 36911009 },
{ 33554432, 73819861, 73819859 },
{ 67108864, 147639589, 147639587 },
{ 134217728, 295279081, 295279079 },
{ 268435456, 590559793, 590559791 }
};
#define NUM_HASH_TABLE_ARRANGEMENTS (sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0]))
struct _cairo_hash_table {
cairo_hash_keys_equal_func_t keys_equal;
const cairo_hash_table_arrangement_t *arrangement;
cairo_hash_entry_t **entries;
unsigned long live_entries;
};
/**
* _cairo_hash_table_create:
* @keys_equal: a function to return TRUE if two keys are equal
*
* Creates a new hash table which will use the keys_equal() function
* to compare hash keys. Data is provided to the hash table in the
* form of user-derived versions of cairo_hash_entry_t. A hash entry
* must be able to hold both a key (including a hash code) and a
* value. Sometimes only the key will be necessary, (as in
* _cairo_hash_table_remove), and other times both a key and a value
* will be necessary, (as in _cairo_hash_table_insert).
*
* See #cairo_hash_entry_t for more details.
*
* Return value: the new hash table or NULL if out of memory.
**/
cairo_hash_table_t *
_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
{
cairo_hash_table_t *hash_table;
hash_table = malloc (sizeof (cairo_hash_table_t));
if (hash_table == NULL)
return NULL;
hash_table->keys_equal = keys_equal;
hash_table->arrangement = &hash_table_arrangements[0];
hash_table->entries = calloc (hash_table->arrangement->size,
sizeof(cairo_hash_entry_t *));
if (hash_table->entries == NULL) {
free (hash_table);
return NULL;
}
hash_table->live_entries = 0;
return hash_table;
}
/**
* _cairo_hash_table_destroy:
* @hash_table: an empty hash table to destroy
*
* Immediately destroys the given hash table, freeing all resources
* associated with it.
*
* WARNING: The hash_table must have no live entries in it before
* _cairo_hash_table_destroy is called. It is a fatal error otherwise,
* and this function will halt. The rationale for this behavior is to
* avoid memory leaks and to avoid needless complication of the API
* with destroy notifiy callbacks.
**/
void
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table)
{
if (hash_table == NULL)
return;
/* The hash table must be empty. Otherwise, halt. */
assert (hash_table->live_entries == 0);
free (hash_table->entries);
hash_table->entries = NULL;
free (hash_table);
}
/**
* _cairo_hash_table_lookup_internal:
*
* @hash_table: a #cairo_hash_table_t to search
* @key: the key to search on
* @hash_code: the hash_code for @key
* @key_unique: If TRUE, then caller asserts that no key already
* exists that will compare equal to #key, so search can be
* optimized. If unsure, set to FALSE and the code will always work.
*
* Search the hashtable for a live entry for which
* hash_table->keys_equal returns true. If no such entry exists then
* return the first available (free or dead entry).
*
* If the key_unique flag is set, then the search will never call
* hash_table->keys_equal and will act as if it always returned
* false. This is useful as a performance optimization in special
* circumstances where the caller knows that there is no existing
* entry in the hash table with a matching key.
*
* Return value: The matching entry in the hash table (if
* any). Otherwise, the first available entry. The caller should check
* entry->state to check whether a match was found or not.
**/
static cairo_hash_entry_t **
_cairo_hash_table_lookup_internal (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key,
cairo_bool_t key_is_unique)
{
cairo_hash_entry_t **entry, **first_available = NULL;
unsigned long table_size, i, idx, step;
table_size = hash_table->arrangement->size;
idx = key->hash % table_size;
step = 0;
for (i = 0; i < table_size; ++i)
{
entry = &hash_table->entries[idx];
if (ENTRY_IS_FREE(*entry))
{
return entry;
}
else if (ENTRY_IS_DEAD(*entry))
{
if (key_is_unique) {
return entry;
} else {
if (! first_available)
first_available = entry;
}
}
else /* ENTRY_IS_LIVE(*entry) */
{
if (! key_is_unique)
if (hash_table->keys_equal (key, *entry))
return entry;
}
if (step == 0) {
step = key->hash % hash_table->arrangement->rehash;
if (step == 0)
step = 1;
}
idx += step;
if (idx >= table_size)
idx -= table_size;
}
/*
* The table should not have permitted you to get here if you were just
* looking for a free slot: there should have been room.
*/
assert (key_is_unique == 0);
return first_available;
}
/**
* _cairo_hash_table_resize:
* @hash_table: a hash table
*
* Resize the hash table if the number of entries has gotten much
* bigger or smaller than the ideal number of entries for the current
* size.
*
* Return value: CAIRO_STATUS_SUCCESS if successful or
* CAIRO_STATUS_NO_MEMORY if out of memory.
**/
static cairo_status_t
_cairo_hash_table_resize (cairo_hash_table_t *hash_table)
{
cairo_hash_table_t tmp;
cairo_hash_entry_t **entry;
unsigned long new_size, i;
/* This keeps the hash table between 25% and 50% full. */
unsigned long high = hash_table->arrangement->high_water_mark;
unsigned long low = high >> 2;
if (hash_table->live_entries >= low && hash_table->live_entries <= high)
return CAIRO_STATUS_SUCCESS;
tmp = *hash_table;
if (hash_table->live_entries > high)
{
tmp.arrangement = hash_table->arrangement + 1;
/* This code is being abused if we can't make a table big enough. */
assert (tmp.arrangement - hash_table_arrangements <
NUM_HASH_TABLE_ARRANGEMENTS);
}
else /* hash_table->live_entries < low */
{
/* Can't shrink if we're at the smallest size */
if (hash_table->arrangement == &hash_table_arrangements[0])
return CAIRO_STATUS_SUCCESS;
tmp.arrangement = hash_table->arrangement - 1;
}
new_size = tmp.arrangement->size;
tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
if (tmp.entries == NULL)
return CAIRO_STATUS_NO_MEMORY;
for (i = 0; i < hash_table->arrangement->size; ++i) {
if (ENTRY_IS_LIVE (hash_table->entries[i])) {
entry = _cairo_hash_table_lookup_internal (&tmp,
hash_table->entries[i],
TRUE);
assert (ENTRY_IS_FREE(*entry));
*entry = hash_table->entries[i];
}
}
free (hash_table->entries);
hash_table->entries = tmp.entries;
hash_table->arrangement = tmp.arrangement;
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_hash_table_lookup:
* @hash_table: a hash table
* @key: the key of interest
* @entry_return: pointer for return value.
*
* Performs a lookup in @hash_table looking for an entry which has a
* key that matches @key, (as determined by the keys_equal() function
* passed to _cairo_hash_table_create).
*
* Return value: TRUE if there is an entry in the hash table that
* matches the given key, (which will now be in *entry_return). FALSE
* otherwise, (in which case *entry_return will be NULL).
**/
cairo_bool_t
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key,
cairo_hash_entry_t **entry_return)
{
cairo_hash_entry_t **entry;
/* See if we have an entry in the table already. */
entry = _cairo_hash_table_lookup_internal (hash_table, key, FALSE);
if (ENTRY_IS_LIVE(*entry)) {
*entry_return = *entry;
return TRUE;
}
*entry_return = NULL;
return FALSE;
}
/**
* _cairo_hash_table_random_entry:
* @hash_table: a hash table
* @predicate: a predicate function, or NULL for any entry.
*
* Find a random entry in the hash table satisfying the given
* @predicate. A NULL @predicate is taken as equivalent to a function
* which always returns TRUE, (eg. any entry in the table will do).
*
* We use the same algorithm as the lookup algorithm to walk over the
* entries in the hash table in a pseudo-random order. Walking
* linearly would favor entries following gaps in the hash table. We
* could also call rand() repeatedly, which works well for almost-full
* tables, but degrades when the table is almost empty, or predicate
* returns TRUE for most entries.
*
* Return value: a random live entry or NULL if there are no entries
* that match the given predicate. In particular, if predicate is
* NULL, a NULL return value indicates that the table is empty.
**/
void *
_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
cairo_hash_predicate_func_t predicate)
{
cairo_hash_entry_t **entry;
unsigned long hash;
unsigned long table_size, i, idx, step;
table_size = hash_table->arrangement->size;
hash = rand ();
idx = hash % table_size;
step = 0;
for (i = 0; i < table_size; ++i)
{
entry = &hash_table->entries[idx];
if (ENTRY_IS_LIVE (*entry) &&
(predicate == NULL || predicate (*entry)))
{
return *entry;
}
if (step == 0) {
step = hash % hash_table->arrangement->rehash;
if (step == 0)
step = 1;
}
idx += step;
if (idx >= table_size)
idx -= table_size;
}
return NULL;
}
/**
* _cairo_hash_table_insert:
* @hash_table: a hash table
* @key_and_value: an entry to be inserted
*
* Insert the entry #key_and_value into the hash table.
*
* WARNING: It is a fatal error if an entry exists in the hash table
* with a matching key, (this function will halt).
*
* Instead of using insert to replace an entry, consider just editing
* the entry obtained with _cairo_hash_table_lookup. Or if absolutely
* necessary, use _cairo_hash_table_remove first.
*
* Return value: CAIRO_STATUS_SUCCESS if successful or
* CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
**/
cairo_status_t
_cairo_hash_table_insert (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key_and_value)
{
cairo_status_t status;
cairo_hash_entry_t **entry;
entry = _cairo_hash_table_lookup_internal (hash_table,
key_and_value, FALSE);
if (ENTRY_IS_LIVE(*entry))
{
/* User is being bad, let's crash. */
ASSERT_NOT_REACHED;
}
*entry = key_and_value;
hash_table->live_entries++;
status = _cairo_hash_table_resize (hash_table);
if (status)
return status;
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_hash_table_remove:
* @hash_table: a hash table
* @key: key of entry to be removed
*
* Remove an entry from the hash table which has a key that matches
* @key, if any (as determined by the keys_equal() function passed to
* _cairo_hash_table_create).
*
* Return value: CAIRO_STATUS_SUCCESS if successful or
* CAIRO_STATUS_NO_MEMORY if out of memory.
**/
void
_cairo_hash_table_remove (cairo_hash_table_t *hash_table,
cairo_hash_entry_t *key)
{
cairo_hash_entry_t **entry;
entry = _cairo_hash_table_lookup_internal (hash_table, key, FALSE);
if (! ENTRY_IS_LIVE(*entry))
return;
*entry = DEAD_ENTRY;
hash_table->live_entries--;
/* This call _can_ fail, but only in failing to allocate new
* memory to shrink the hash table. It does leave the table in a
* consistent state, and we've already succeeded in removing the
* entry, so we don't examine the failure status of this call. */
_cairo_hash_table_resize (hash_table);
}
/**
* _cairo_hash_table_foreach:
* @hash_table: a hash table
* @hash_callback: function to be called for each live entry
* @closure: additional argument to be passed to @hash_callback
*
* Call @hash_callback for each live entry in the hash table, in a
* non-specified order.
**/
void
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
cairo_hash_callback_func_t hash_callback,
void *closure)
{
unsigned long i;
cairo_hash_entry_t *entry;
if (hash_table == NULL)
return;
for (i = 0; i < hash_table->arrangement->size; i++) {
entry = hash_table->entries[i];
if (ENTRY_IS_LIVE(entry))
hash_callback (entry, closure);
}
}

Просмотреть файл

@ -36,8 +36,6 @@
#include "cairoint.h"
static const cairo_surface_backend_t cairo_image_surface_backend;
static int
_cairo_format_bpp (cairo_format_t format)
{
@ -53,15 +51,17 @@ _cairo_format_bpp (cairo_format_t format)
}
}
static cairo_image_surface_t *
static cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format)
{
cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_image_surface_backend);
@ -69,24 +69,25 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
surface->format = format;
surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
surface->owns_data = 0;
surface->owns_data = FALSE;
surface->has_clip = FALSE;
surface->width = pixman_image_get_width (pixman_image);
surface->height = pixman_image_get_height (pixman_image);
surface->stride = pixman_image_get_stride (pixman_image);
surface->depth = pixman_image_get_depth (pixman_image);
return surface;
return &surface->base;
}
cairo_image_surface_t *
cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
cairo_format_masks_t *format,
int width,
int height,
int stride)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
@ -96,16 +97,20 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
format->green_mask,
format->blue_mask);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height, format->bpp, stride);
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
(cairo_format_t)-1);
@ -152,24 +157,31 @@ cairo_image_surface_create (cairo_format_t format,
int width,
int height)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
return (cairo_surface_t*) &_cairo_surface_nil;
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create (pixman_format, width, height);
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
return surface;
}
/**
@ -201,13 +213,18 @@ cairo_image_surface_create_for_data (unsigned char *data,
int height,
int stride)
{
cairo_image_surface_t *surface;
cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
return (cairo_surface_t*) &_cairo_surface_nil;
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL)
return NULL;
if (pixman_format == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height,
@ -216,12 +233,14 @@ cairo_image_surface_create_for_data (unsigned char *data,
pixman_format_destroy (pixman_format);
if (pixman_image == NULL)
return NULL;
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
return surface;
}
/**
@ -237,6 +256,11 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
return image_surface->width;
}
@ -253,17 +277,57 @@ cairo_image_surface_get_height (cairo_surface_t *surface)
{
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
if (!_cairo_surface_is_image (surface)) {
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
return image_surface->height;
}
cairo_format_t
_cairo_format_from_content (cairo_content_t content)
{
switch (content) {
case CAIRO_CONTENT_COLOR:
return CAIRO_FORMAT_RGB24;
case CAIRO_CONTENT_ALPHA:
return CAIRO_FORMAT_A8;
case CAIRO_CONTENT_COLOR_ALPHA:
return CAIRO_FORMAT_ARGB32;
}
ASSERT_NOT_REACHED;
return CAIRO_FORMAT_ARGB32;
}
cairo_content_t
_cairo_content_from_format (cairo_format_t format)
{
switch (format) {
case CAIRO_FORMAT_ARGB32:
return CAIRO_CONTENT_COLOR_ALPHA;
case CAIRO_FORMAT_RGB24:
return CAIRO_CONTENT_COLOR;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
return CAIRO_CONTENT_ALPHA;
}
ASSERT_NOT_REACHED;
return CAIRO_CONTENT_COLOR_ALPHA;
}
static cairo_surface_t *
_cairo_image_surface_create_similar (void *abstract_src,
cairo_format_t format,
int drawable,
_cairo_image_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height)
{
return cairo_image_surface_create (format, width, height);
assert (CAIRO_CONTENT_VALID (content));
return cairo_image_surface_create (_cairo_format_from_content (content),
width, height);
}
static cairo_status_t
@ -296,6 +360,7 @@ _cairo_image_surface_acquire_source_image (void *abstract_sur
void **image_extra)
{
*image_out = abstract_surface;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -322,7 +387,8 @@ _cairo_image_surface_acquire_dest_image (void *abstract_surfa
image_rect_out->height = surface->height;
*image_out = surface;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -343,8 +409,7 @@ _cairo_image_surface_clone_similar (void *abstract_surface,
cairo_image_surface_t *surface = abstract_surface;
if (src->backend == surface->base.backend) {
*clone_out = src;
cairo_surface_reference (src);
*clone_out = cairo_surface_reference (src);
return CAIRO_STATUS_SUCCESS;
}
@ -352,7 +417,7 @@ _cairo_image_surface_clone_similar (void *abstract_surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
cairo_status_t
static cairo_status_t
_cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
const cairo_matrix_t *matrix)
{
@ -375,7 +440,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
static cairo_status_t
_cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t filter)
{
pixman_filter_t pixman_filter;
@ -405,7 +470,7 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
static cairo_status_t
_cairo_image_surface_set_repeat (cairo_image_surface_t *surface, int repeat)
{
pixman_image_set_repeat (surface->pixman_image, repeat);
@ -518,41 +583,54 @@ _cairo_image_surface_composite (cairo_operator_t operator,
return status;
status = _cairo_image_surface_set_attributes (src, &src_attr);
if (CAIRO_OK (status))
{
if (mask)
{
status = _cairo_image_surface_set_attributes (mask, &mask_attr);
if (CAIRO_OK (status))
pixman_composite (_pixman_operator (operator),
src->pixman_image,
mask->pixman_image,
dst->pixman_image,
src_x + src_attr.x_offset,
src_y + src_attr.y_offset,
mask_x + mask_attr.x_offset,
mask_y + mask_attr.y_offset,
dst_x, dst_y,
width, height);
}
else
{
pixman_composite (_pixman_operator (operator),
src->pixman_image,
NULL,
dst->pixman_image,
src_x + src_attr.x_offset,
src_y + src_attr.y_offset,
0, 0,
dst_x, dst_y,
width, height);
}
}
if (status)
goto CLEANUP_SURFACES;
if (mask)
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
{
status = _cairo_image_surface_set_attributes (mask, &mask_attr);
if (status)
goto CLEANUP_SURFACES;
pixman_composite (_pixman_operator (operator),
src->pixman_image,
mask->pixman_image,
dst->pixman_image,
src_x + src_attr.x_offset,
src_y + src_attr.y_offset,
mask_x + mask_attr.x_offset,
mask_y + mask_attr.y_offset,
dst_x, dst_y,
width, height);
}
else
{
pixman_composite (_pixman_operator (operator),
src->pixman_image,
NULL,
dst->pixman_image,
src_x + src_attr.x_offset,
src_y + src_attr.y_offset,
0, 0,
dst_x, dst_y,
width, height);
}
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
if (!_cairo_operator_bounded (operator))
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
&src_attr, src->width, src->height,
mask ? &mask_attr : NULL,
mask ? mask->width : 0,
mask ? mask->height : 0,
src_x, src_y,
mask_x, mask_y,
dst_x, dst_y, width, height);
CLEANUP_SURFACES:
if (mask)
_cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr);
_cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
return status;
}
@ -580,10 +658,25 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
_cairo_image_surface_is_alpha_only (cairo_image_surface_t *surface)
{
int bpp, alpha, red, green, blue;
if (surface->format != (cairo_format_t) -1)
return surface->format == CAIRO_FORMAT_A1 || surface->format == CAIRO_FORMAT_A8;
pixman_format_get_masks (pixman_image_get_format (surface->pixman_image),
&bpp, &alpha, &red, &green, &blue);
return red == 0 && blue == 0 && green == 0;
}
static cairo_int_status_t
_cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
int src_y,
int dst_x,
@ -597,8 +690,35 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_t *src;
cairo_int_status_t status;
int render_reference_x, render_reference_y;
int render_src_x, render_src_y;
pixman_image_t *mask;
pixman_format_t *format;
pixman_bits_t *mask_data;
int mask_stride;
int mask_bpp;
/* Special case adding trapezoids onto a mask surface; we want to avoid
* creating an intermediate temporary mask unecessarily.
*
* We make the assumption here that the portion of the trapezoids
* contained within the surface is bounded by [dst_x,dst_y,width,height];
* the Cairo core code passes bounds based on the trapezoid extents.
*
* Currently the check surface->has_clip is needed for correct
* functioning, since pixman_add_trapezoids() doesn't obey the
* surface clip, which is a libpixman bug , but there's no harm in
* 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 &&
_cairo_pattern_is_opaque_solid (pattern) &&
_cairo_image_surface_is_alpha_only (dst) &&
!dst->has_clip &&
antialias != CAIRO_ANTIALIAS_NONE)
{
pixman_add_trapezoids (dst->pixman_image, 0, 0,
(pixman_trapezoid_t *) traps, num_traps);
return CAIRO_STATUS_SUCCESS;
}
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
src_x, src_y, width, height,
@ -607,29 +727,72 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
if (status)
return status;
if (traps[0].left.p1.y < traps[0].left.p2.y) {
render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x);
render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p1.y);
} else {
render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p2.x);
render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p2.y);
status = _cairo_image_surface_set_attributes (src, &attributes);
if (status)
goto CLEANUP_SOURCE;
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
format = pixman_format_create (PIXMAN_FORMAT_NAME_A1);
mask_stride = (width + 31)/8;
mask_bpp = 1;
break;
default:
format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
mask_stride = (width + 3) & ~3;
mask_bpp = 8;
break;
}
if (!format) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_SOURCE;
}
render_src_x = src_x + render_reference_x - dst_x;
render_src_y = src_y + render_reference_y - dst_y;
/* The image must be initially transparent */
mask_data = calloc (1, mask_stride * height);
if (!mask_data) {
status = CAIRO_STATUS_NO_MEMORY;
pixman_format_destroy (format);
goto CLEANUP_SOURCE;
}
mask = pixman_image_create_for_data (mask_data, format, width, height,
mask_bpp, mask_stride);
pixman_format_destroy (format);
if (!mask) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_IMAGE_DATA;
}
/* XXX: The pixman_trapezoid_t cast is evil and needs to go away
* somehow. */
status = _cairo_image_surface_set_attributes (src, &attributes);
if (CAIRO_OK (status))
pixman_composite_trapezoids (_pixman_operator (operator),
src->pixman_image,
dst->pixman_image,
render_src_x + attributes.x_offset,
render_src_y + attributes.y_offset,
(pixman_trapezoid_t *) traps, num_traps);
pixman_add_trapezoids (mask, - dst_x, - dst_y,
(pixman_trapezoid_t *) traps, num_traps);
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
pixman_composite (_pixman_operator (operator),
src->pixman_image,
mask,
dst->pixman_image,
src_x + attributes.x_offset,
src_y + attributes.y_offset,
0, 0,
dst_x, dst_y,
width, height);
if (!_cairo_operator_bounded (operator))
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
&attributes, src->width, src->height,
width, height,
src_x, src_y,
0, 0,
dst_x, dst_y, width, height);
pixman_image_destroy (mask);
CLEANUP_IMAGE_DATA:
free (mask_data);
CLEANUP_SOURCE:
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
return status;
}
@ -647,20 +810,9 @@ cairo_int_status_t
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
pixman_region16_t *region)
{
if (region) {
pixman_region16_t *rcopy;
pixman_image_set_clip_region (surface->pixman_image, region);
rcopy = pixman_region_create();
/* pixman_image_set_clip_region expects to take ownership of the
* passed-in region, so we create a copy to give it. */
/* XXX: I think that's probably a bug in pixman. But its
* memory management issues need auditing anyway, so a
* workaround like this is fine for now. */
pixman_region_copy (rcopy, region);
pixman_image_set_clip_region (surface->pixman_image, rcopy);
} else {
pixman_image_set_clip_region (surface->pixman_image, region);
}
surface->has_clip = region != NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -692,15 +844,15 @@ _cairo_image_abstract_surface_get_extents (void *abstract_surface,
*
* Checks if a surface is an #cairo_image_surface_t
*
* Return value: True if the surface is an image surface
* Return value: TRUE if the surface is an image surface
**/
int
cairo_bool_t
_cairo_surface_is_image (cairo_surface_t *surface)
{
return surface->backend == &cairo_image_surface_backend;
}
static const cairo_surface_backend_t 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_acquire_source_image,
@ -714,6 +866,7 @@ static const cairo_surface_backend_t cairo_image_surface_backend = {
NULL, /* copy_page */
NULL, /* show_page */
_cairo_image_abstract_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_image_abstract_surface_get_extents,
NULL /* show_glyphs */
};

Просмотреть файл

@ -525,7 +525,9 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
_cairo_matrix_compute_determinant (matrix, &det);
if (det == 0)
{
*sx = *sy = 0;
}
else
{
double x = x_major != 0;
@ -558,49 +560,30 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
return CAIRO_STATUS_SUCCESS;
}
/* Compute the min/max expansion factors. See the comment in
* cairo-pen.c for the derivation */
cairo_status_t
_cairo_matrix_compute_expansion_factors (const cairo_matrix_t *matrix,
double *min, double *max)
{
double a = matrix->xx, b = matrix->yx;
double c = matrix->xy, d = matrix->yy;
double i = a*a + c*c;
double j = b*b + d*d;
double f = 0.5 * (i + j);
double g = 0.5 * (i - j);
double h = a*b + c*d;
*max = sqrt (f + sqrt (g*g+h*h));
*min = sqrt (f - sqrt (g*g+h*h));
return CAIRO_STATUS_SUCCESS;
}
cairo_bool_t
_cairo_matrix_is_integer_translation(const cairo_matrix_t *mat,
_cairo_matrix_is_integer_translation(const cairo_matrix_t *m,
int *itx, int *ity)
{
double a, b, c, d, tx, ty;
int ttx, tty;
int ok = 0;
_cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
ttx = _cairo_fixed_from_double (tx);
tty = _cairo_fixed_from_double (ty);
ok = ((a == 1.0)
&& (b == 0.0)
&& (c == 0.0)
&& (d == 1.0)
&& (_cairo_fixed_is_integer(ttx))
&& (_cairo_fixed_is_integer(tty)));
if (ok) {
*itx = _cairo_fixed_integer_part(ttx);
*ity = _cairo_fixed_integer_part(tty);
return TRUE;
}
return FALSE;
cairo_bool_t is_integer_translation;
cairo_fixed_t x0_fixed, y0_fixed;
x0_fixed = _cairo_fixed_from_double (m->x0);
y0_fixed = _cairo_fixed_from_double (m->y0);
is_integer_translation = ((m->xx == 1.0) &&
(m->yx == 0.0) &&
(m->xy == 0.0) &&
(m->yy == 1.0) &&
(_cairo_fixed_is_integer(x0_fixed)) &&
(_cairo_fixed_is_integer(y0_fixed)));
if (! is_integer_translation)
return FALSE;
if (itx)
*itx = _cairo_fixed_integer_part(x0_fixed);
if (ity)
*ity = _cairo_fixed_integer_part(y0_fixed);
return TRUE;
}

Просмотреть файл

@ -0,0 +1,155 @@
/* 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):
* Kristian Høgsberg <krh@redhat.com>
*/
#ifndef CAIRO_META_SURFACE_H
#define CAIRO_META_SURFACE_H
#include "cairoint.h"
#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,
CAIRO_COMMAND_SHOW_GLYPHS,
CAIRO_COMMAND_FILL_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_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_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_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_intersect_clip_path {
cairo_command_type_t type;
cairo_path_fixed_t *path_pointer;
cairo_path_fixed_t path;
cairo_fill_rule_t fill_rule;
double tolerance;
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;
cairo_command_show_glyphs_t show_glyphs;
cairo_command_fill_path_t fill_path;
} cairo_command_t;
typedef struct _cairo_meta_surface {
cairo_surface_t base;
double width, height;
cairo_array_t commands;
} cairo_meta_surface_t;
cairo_private cairo_surface_t *
_cairo_meta_surface_create (double width, double height);
cairo_private cairo_int_status_t
_cairo_meta_surface_replay (cairo_surface_t *surface,
cairo_surface_t *target);
#endif /* CAIRO_META_SURFACE_H */

Просмотреть файл

@ -0,0 +1,592 @@
/* 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):
* Kristian Høgsberg <krh@redhat.com>
*/
#include "cairoint.h"
#include "cairo-meta-surface-private.h"
#include "cairo-gstate-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_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;
}
meta->width = width;
meta->height = height;
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
return &meta->base;
}
static cairo_surface_t *
_cairo_meta_surface_create_similar (void *abstract_surface,
cairo_content_t content,
int width,
int height)
{
return _cairo_meta_surface_create (width, height);
}
static cairo_status_t
_cairo_meta_surface_finish (void *abstract_surface)
{
cairo_meta_surface_t *meta = abstract_surface;
cairo_command_t *command;
cairo_command_t **elements;
int i, num_elements;
num_elements = meta->commands.num_elements;
elements = (cairo_command_t **) meta->commands.elements;
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);
free (command);
break;
case CAIRO_COMMAND_FILL_RECTANGLES:
free (command->fill_rectangles.rects);
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);
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);
free (command->show_glyphs.glyphs);
free (command);
break;
case CAIRO_COMMAND_FILL_PATH:
_cairo_pattern_fini (&command->fill_path.pattern.base);
_cairo_path_fixed_fini (&command->fill_path.path);
free (command);
break;
default:
ASSERT_NOT_REACHED;
}
}
_cairo_array_fini (&meta->commands);
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)
{
cairo_meta_surface_t *meta = abstract_surface;
cairo_command_composite_t *command;
command = malloc (sizeof (cairo_command_composite_t));
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
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;
}
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;
}
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_t *meta = abstract_surface;
cairo_command_fill_rectangles_t *command;
command = malloc (sizeof (cairo_command_fill_rectangles_t));
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_FILL_RECTANGLES;
command->operator = operator;
command->color = *color;
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;
}
return CAIRO_STATUS_SUCCESS;
}
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_t *meta = abstract_surface;
cairo_command_composite_trapezoids_t *command;
command = malloc (sizeof (cairo_command_composite_trapezoids_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->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;
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_meta_surface_intersect_clip_path (void *dst,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_meta_surface_t *meta = dst;
cairo_command_intersect_clip_path_t *command;
cairo_status_t status;
command = malloc (sizeof (cairo_command_intersect_clip_path_t));
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
if (path) {
status = _cairo_path_fixed_init_copy (&command->path, path);
if (status) {
free (command);
return status;
}
command->path_pointer = &command->path;
} else {
command->path_pointer = NULL;
}
command->fill_rule = fill_rule;
command->tolerance = tolerance;
command->antialias = antialias;
if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
if (path)
_cairo_path_fixed_fini (&command->path);
free (command);
return CAIRO_STATUS_NO_MEMORY;
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_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;
}
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_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;
}
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 */
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, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
_cairo_meta_surface_intersect_clip_path,
_cairo_meta_surface_get_extents,
_cairo_meta_surface_show_glyphs,
_cairo_meta_surface_fill_path,
};
cairo_int_status_t
_cairo_meta_surface_replay (cairo_surface_t *surface,
cairo_surface_t *target)
{
cairo_meta_surface_t *meta;
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;
status = CAIRO_STATUS_SUCCESS;
_cairo_clip_init (&clip, target);
num_elements = meta->commands.num_elements;
elements = (cairo_command_t **) meta->commands.elements;
for (i = 0; i < num_elements; i++) {
command = elements[i];
switch (command->type) {
case CAIRO_COMMAND_COMPOSITE:
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);
break;
case CAIRO_COMMAND_FILL_RECTANGLES:
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);
break;
case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
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);
break;
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
/* XXX Meta surface clipping is broken and requires some
* cairo-gstate.c rewriting. Work around it for now. */
if (command->intersect_clip_path.path_pointer == NULL)
status = _cairo_clip_reset (&clip);
else
status = _cairo_clip_clip (&clip,
command->intersect_clip_path.path_pointer,
command->intersect_clip_path.fill_rule,
command->intersect_clip_path.tolerance,
command->intersect_clip_path.antialias,
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);
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;
}
if (status)
break;
}
_cairo_clip_fini (&clip);
return status;
}

Просмотреть файл

@ -39,6 +39,10 @@
#include <ctype.h>
#include "cairoint.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#endif /* _MSC_VER */
struct _cairo_output_stream {
cairo_write_func_t write_data;
void *closure;
@ -90,6 +94,26 @@ _cairo_output_stream_write (cairo_output_stream_t *stream,
return stream->status;
}
void
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
size_t length)
{
const char hex_chars[] = "0123456789abcdef";
char buffer[2];
int i, column;
for (i = 0, column = 0; i < length; i++, column++) {
if (column == 38) {
_cairo_output_stream_write (stream, "\n", 1);
column = 0;
}
buffer[0] = hex_chars[(data[i] >> 4) & 0x0f];
buffer[1] = hex_chars[data[i] & 0x0f];
_cairo_output_stream_write (stream, buffer, 2);
}
}
/* Format a double in a locale independent way and trim trailing
* zeros. Based on code from Alex Larson <alexl@redhat.com>.
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
@ -187,8 +211,8 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
switch (*f | length_modifier) {
case '%':
p[0] = *f;
p[1] = 0;
buffer[0] = *f;
buffer[1] = 0;
break;
case 'd':
snprintf (buffer, sizeof buffer, "%d", va_arg (ap, int));
@ -211,6 +235,10 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
case 'f':
dtostr (buffer, sizeof buffer, va_arg (ap, double));
break;
case 'c':
buffer[0] = va_arg (ap, int);
buffer[1] = 0;
break;
default:
ASSERT_NOT_REACHED;
}

Просмотреть файл

@ -38,17 +38,17 @@
#include "cairoint.h"
extern cairo_path_t _cairo_path_nil;
extern const cairo_private cairo_path_t _cairo_path_nil;
cairo_path_t *
cairo_private cairo_path_t *
_cairo_path_data_create (cairo_path_fixed_t *path,
cairo_gstate_t *gstate);
cairo_path_t *
cairo_private cairo_path_t *
_cairo_path_data_create_flat (cairo_path_fixed_t *path,
cairo_gstate_t *gstate);
cairo_status_t
cairo_private cairo_status_t
_cairo_path_data_append_to_context (cairo_path_t *path,
cairo_t *cr);

Просмотреть файл

@ -37,8 +37,7 @@
#include "cairo-path-fixed-private.h"
#include "cairo-gstate-private.h"
cairo_path_t
_cairo_path_nil = { NULL, 0 };
const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
/* Closure for path interpretation. */
typedef struct cairo_path_data_count {
@ -105,14 +104,18 @@ _cpdc_curve_to_flatten (void *closure,
status = _cairo_spline_decompose (&spline, cpdc->tolerance);
if (status)
return status;
goto out;
for (i=1; i < spline.num_points; i++)
_cpdc_line_to (cpdc, &spline.points[i]);
cpdc->current_point = *p3;
return CAIRO_STATUS_SUCCESS;
status = CAIRO_STATUS_SUCCESS;
out:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t
@ -276,14 +279,18 @@ _cpdp_curve_to_flatten (void *closure,
status = _cairo_spline_decompose (&spline, cpdp->gstate->tolerance);
if (status)
return status;
goto out;
for (i=1; i < spline.num_points; i++)
_cpdp_line_to (cpdp, &spline.points[i]);
cpdp->current_point = *p3;
return CAIRO_STATUS_SUCCESS;
status = CAIRO_STATUS_SUCCESS;
out:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t
@ -339,7 +346,7 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed,
path = malloc (sizeof (cairo_path_t));
if (path == NULL)
return &_cairo_path_nil;
return (cairo_path_t*) &_cairo_path_nil;
path->num_data = _cairo_path_data_count (path, path_fixed,
gstate->tolerance, flatten);
@ -347,23 +354,56 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed,
path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
if (path->data == NULL) {
free (path);
return &_cairo_path_nil;
return (cairo_path_t*) &_cairo_path_nil;
}
path->status = CAIRO_STATUS_SUCCESS;
_cairo_path_data_populate (path, path_fixed,
gstate, flatten);
return path;
}
/**
* cairo_path_destroy:
* @path: a path to destroy which was previously returned by either
* cairo_copy_path or cairo_copy_path_flat.
*
* Immediately releases all memory associated with @path. After a call
* to cairo_path_destroy() the @path pointer is no longer valid and
* should not be used further.
*
* NOTE: cairo_path_destroy function should only be called with a
* pointer to a #cairo_path_t returned by a cairo function. Any path
* that is created manually (ie. outside of cairo) should be destroyed
* manually as well.
**/
void
cairo_path_destroy (cairo_path_t *path)
{
if (path == NULL || path == &_cairo_path_nil)
return;
free (path->data);
path->num_data = 0;
free (path);
}
/**
* _cairo_path_data_create:
* @path: a fixed-point, device-space path to be converted and copied
* @gstate: the current graphics state
*
* Creates a user-space #cairo_path_t copy of the given device-space
* @path. The @gstate parameter provides the inverse CTM for the
* conversion.
*
* Return value: the new copy of the path. If there is insufficient
* memory a pointer to a special static cairo_path_nil will be
* returned instead with status==CAIRO_STATUS_NO_MEMORY and
* data==NULL.
**/
cairo_path_t *
_cairo_path_data_create (cairo_path_fixed_t *path,
cairo_gstate_t *gstate)
@ -371,6 +411,21 @@ _cairo_path_data_create (cairo_path_fixed_t *path,
return _cairo_path_data_create_real (path, gstate, FALSE);
}
/**
* _cairo_path_data_create_flat:
* @path: a fixed-point, device-space path to be flattened, converted and copied
* @gstate: the current graphics state
*
* Creates a flattened, user-space #cairo_path_t copy of the given
* device-space @path. The @gstate parameter provide the inverse CTM
* for the conversion, as well as the tolerance value to control the
* accuracy of the flattening.
*
* Return value: the flattened copy of the path. If there is insufficient
* memory a pointer to a special static cairo_path_nil will be
* returned instead with status==CAIRO_STATUS_NO_MEMORY and
* data==NULL.
**/
cairo_path_t *
_cairo_path_data_create_flat (cairo_path_fixed_t *path,
cairo_gstate_t *gstate)
@ -378,6 +433,16 @@ _cairo_path_data_create_flat (cairo_path_fixed_t *path,
return _cairo_path_data_create_real (path, gstate, TRUE);
}
/**
* _cairo_path_data_append_to_context:
* @path: the path data to be appended
* @cr: a cairo context
*
* Append @path to the current path within @cr.
*
* Return value: CAIRO_STATUS_INVALID_PATH_DATA if the data in @path
* is invalid, and CAIRO_STATUS_SUCCESS otherwise.
**/
cairo_status_t
_cairo_path_data_append_to_context (cairo_path_t *path,
cairo_t *cr)
@ -389,29 +454,29 @@ _cairo_path_data_append_to_context (cairo_path_t *path,
p = &path->data[i];
switch (p->header.type) {
case CAIRO_PATH_MOVE_TO:
if (p->header.length != 2)
return CAIRO_STATUS_INVALID_PATH_DATA;
cairo_move_to (cr,
p[1].point.x, p[1].point.y);
if (p->header.length != 2)
return CAIRO_STATUS_INVALID_PATH_DATA;
break;
case CAIRO_PATH_LINE_TO:
cairo_line_to (cr,
p[1].point.x, p[1].point.y);
if (p->header.length != 2)
return CAIRO_STATUS_INVALID_PATH_DATA;
cairo_line_to (cr,
p[1].point.x, p[1].point.y);
break;
case CAIRO_PATH_CURVE_TO:
if (p->header.length != 4)
return CAIRO_STATUS_INVALID_PATH_DATA;
cairo_curve_to (cr,
p[1].point.x, p[1].point.y,
p[2].point.x, p[2].point.y,
p[3].point.x, p[3].point.y);
if (p->header.length != 4)
return CAIRO_STATUS_INVALID_PATH_DATA;
break;
case CAIRO_PATH_CLOSE_PATH:
cairo_close_path (cr);
if (p->header.length != 1)
return CAIRO_STATUS_INVALID_PATH_DATA;
cairo_close_path (cr);
break;
default:
return CAIRO_STATUS_INVALID_PATH_DATA;

Просмотреть файл

@ -36,10 +36,8 @@
#include "cairoint.h"
#include "cairo-gstate-private.h"
typedef struct cairo_filler {
cairo_gstate_t *gstate;
double tolerance;
cairo_traps_t *traps;
cairo_point_t current_point;
@ -48,7 +46,7 @@ typedef struct cairo_filler {
} cairo_filler_t;
static void
_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps);
_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps);
static void
_cairo_filler_fini (cairo_filler_t *filler);
@ -69,9 +67,9 @@ static cairo_status_t
_cairo_filler_close_path (void *closure);
static void
_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps)
_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps)
{
filler->gstate = gstate;
filler->tolerance = tolerance;
filler->traps = traps;
filler->current_point.x = 0;
@ -132,7 +130,6 @@ _cairo_filler_curve_to (void *closure,
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_filler_t *filler = closure;
cairo_polygon_t *polygon = &filler->polygon;
cairo_gstate_t *gstate = filler->gstate;
cairo_spline_t spline;
status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
@ -140,7 +137,7 @@ _cairo_filler_curve_to (void *closure,
if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS;
_cairo_spline_decompose (&spline, gstate->tolerance);
_cairo_spline_decompose (&spline, filler->tolerance);
if (status)
goto CLEANUP_SPLINE;
@ -174,13 +171,14 @@ _cairo_filler_close_path (void *closure)
cairo_status_t
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
cairo_gstate_t *gstate,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_traps_t *traps)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_filler_t filler;
_cairo_filler_init (&filler, gstate, traps);
_cairo_filler_init (&filler, tolerance, traps);
status = _cairo_path_fixed_interpret (path,
CAIRO_DIRECTION_FORWARD,
@ -198,7 +196,7 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
status = _cairo_traps_tessellate_polygon (filler.traps,
&filler.polygon,
filler.gstate->fill_rule);
fill_rule);
if (status)
goto BAIL;

Просмотреть файл

@ -50,20 +50,92 @@ typedef struct _cairo_shader_op {
((unsigned char) \
((((unsigned char) (c1)) * (int) ((unsigned char) (c2))) / 0xff))
const cairo_solid_pattern_t cairo_solid_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 */
{ 0.0, 0.0, 0.0, 1.0, /* solid black */
0x0, 0x0, 0x0, 0xffff }
};
static const cairo_surface_pattern_t cairo_surface_pattern_nil = {
{ CAIRO_PATTERN_SURFACE, /* 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 */
NULL /* surface */
};
static const cairo_linear_pattern_t cairo_linear_pattern_nil = {
{ { CAIRO_PATTERN_LINEAR, /* 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 */
NULL, /* stops */
0 }, /* n_stops */
{ 0., 0. }, { 1.0, 1.0 } /* point0, point1 */
};
static const cairo_radial_pattern_t cairo_radial_pattern_nil = {
{ { CAIRO_PATTERN_RADIAL, /* 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 */
NULL, /* stops */
0 }, /* n_stops */
{ 0., 0. }, { 0.0, 0.0 }, /* center0, center1 */
1.0, 1.0, /* radius0, radius1 */
};
/**
* _cairo_pattern_set_error:
* @pattern: a pattern
* @status: a status value indicating an error, (eg. not
* CAIRO_STATUS_SUCCESS)
*
* Sets pattern->status to @status and calls _cairo_error;
*
* All assignments of an error status to pattern->status should happen
* through _cairo_pattern_set_error() or else _cairo_error() should be
* called immediately after the assignment.
*
* The purpose of this function is to allow the user to set a
* breakpoint in _cairo_error() to generate a stack trace for when the
* user causes cairo to detect an error.
**/
static void
_cairo_pattern_set_error (cairo_pattern_t *pattern,
cairo_status_t status)
{
pattern->status = status;
_cairo_error (status);
}
static void
_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;
pattern->filter = CAIRO_FILTER_DEFAULT;
cairo_matrix_init_identity (&pattern->matrix);
}
static cairo_status_t
_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
cairo_gradient_pattern_t *other)
static void
_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
const cairo_gradient_pattern_t *other)
{
if (other->base.type == CAIRO_PATTERN_LINEAR)
{
@ -80,21 +152,28 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
*dst = *src;
}
if (other->base.status)
_cairo_pattern_set_error (&pattern->base, other->base.status);
if (other->n_stops)
{
pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
if (!pattern->stops)
return CAIRO_STATUS_NO_MEMORY;
if (pattern->stops == NULL) {
if (other->base.type == CAIRO_PATTERN_LINEAR)
_cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base);
else
_cairo_gradient_pattern_init_copy (pattern, &cairo_radial_pattern_nil.base);
return;
}
memcpy (pattern->stops, other->stops,
other->n_stops * sizeof (cairo_color_stop_t));
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other)
void
_cairo_pattern_init_copy (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
switch (other->type) {
case CAIRO_PATTERN_SOLID: {
@ -114,17 +193,12 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other)
case CAIRO_PATTERN_RADIAL: {
cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
cairo_status_t status;
status = _cairo_gradient_pattern_init_copy (dst, src);
if (status)
return status;
_cairo_gradient_pattern_init_copy (dst, src);
} break;
}
pattern->ref_count = 1;
return CAIRO_STATUS_SUCCESS;
}
void
@ -162,8 +236,7 @@ _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern,
{
_cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SURFACE);
pattern->surface = surface;
cairo_surface_reference (surface);
pattern->surface = cairo_surface_reference (surface);
}
static void
@ -210,47 +283,195 @@ _cairo_pattern_create_solid (const cairo_color_t *color)
pattern = malloc (sizeof (cairo_solid_pattern_t));
if (pattern == NULL)
return NULL;
return (cairo_pattern_t *) &cairo_solid_pattern_nil.base;
_cairo_pattern_init_solid (pattern, color);
return &pattern->base;
}
/**
* cairo_pattern_create_rgb:
* @red: red component of the color
* @green: green component of the color
* @blue: blue component of the color
*
* Creates a new cairo_pattern_t corresponding to an opaque color. The
* color components are floating point numbers in the range 0 to 1.
* If the values passed in are outside that range, they will be
* clamped.
*
* Return value: the newly created #cairo_pattern_t if succesful, or
* an error pattern in case of no memory. The caller owns the
* returned object and should call cairo_pattern_destroy() when
* finished with it.
*
* This function will always return a valid pointer, but if an error
* occurred the pattern status will be set to an error. To inspect
* the status of a pattern use cairo_pattern_status().
**/
cairo_pattern_t *
cairo_pattern_create_rgb (double red, double green, double blue)
{
cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
_cairo_restrict_value (&green, 0.0, 1.0);
_cairo_restrict_value (&blue, 0.0, 1.0);
_cairo_color_init_rgb (&color, red, green, blue);
pattern = _cairo_pattern_create_solid (&color);
if (pattern->status)
_cairo_pattern_set_error (pattern, pattern->status);
return pattern;
}
/**
* cairo_pattern_create_rgba:
* @red: red component of the color
* @green: green component of the color
* @blue: blue component of the color
* @alpha: alpha component of the color
*
* Creates a new cairo_pattern_t corresponding to a translucent color.
* The color components are floating point numbers in the range 0 to
* 1. If the values passed in are outside that range, they will be
* clamped.
*
* Return value: the newly created #cairo_pattern_t if succesful, or
* an error pattern in case of no memory. The caller owns the
* returned object and should call cairo_pattern_destroy() when
* finished with it.
*
* This function will always return a valid pointer, but if an error
* occurred the pattern status will be set to an error. To inspect
* the status of a pattern use cairo_pattern_status().
**/
cairo_pattern_t *
cairo_pattern_create_rgba (double red, double green, double blue,
double alpha)
{
cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
_cairo_restrict_value (&green, 0.0, 1.0);
_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);
pattern = _cairo_pattern_create_solid (&color);
if (pattern->status)
_cairo_pattern_set_error (pattern, pattern->status);
return pattern;
}
/**
* cairo_pattern_create_for_surface:
* @surface: the surface
*
* Create a new cairo_pattern_t for the given surface.
*
* Return value: the newly created #cairo_pattern_t if succesful, or
* an error pattern in case of no memory. The caller owns the
* returned object and should call cairo_pattern_destroy() when
* finished with it.
*
* This function will always return a valid pointer, but if an error
* occurred the pattern status will be set to an error. To inspect
* the status of a pattern use cairo_pattern_status().
**/
cairo_pattern_t *
cairo_pattern_create_for_surface (cairo_surface_t *surface)
{
cairo_surface_pattern_t *pattern;
pattern = malloc (sizeof (cairo_surface_pattern_t));
if (pattern == NULL)
return NULL;
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&cairo_surface_pattern_nil.base;
}
_cairo_pattern_init_for_surface (pattern, surface);
/* this will go away when we completely remove the surface attributes */
if (surface->repeat)
pattern->base.extend = CAIRO_EXTEND_REPEAT;
else
pattern->base.extend = CAIRO_EXTEND_DEFAULT;
return &pattern->base;
}
/**
* cairo_pattern_create_linear:
* @x0: x coordinate of the start point
* @y0: y coordinate of the start point
* @x1: x coordinate of the end point
* @y1: y coordinate of the end point
*
* Create a new linear gradient cairo_pattern_t along the line defined
* by (x0, y0) and (x1, y1). Before using the gradient pattern, a
* number of color stops should be defined using
* cairo_pattern_add_color_stop_rgb() or
* cairo_pattern_add_color_stop_rgba().
*
* Note: The coordinates here are in pattern space. For a new pattern,
* pattern space is identical to user space, but the relationship
* between the spaces can be changed with cairo_pattern_set_matrix().
*
* Return value: the newly created #cairo_pattern_t if succesful, or
* an error pattern in case of no memory. The caller owns the
* returned object and should call cairo_pattern_destroy() when
* finished with it.
*
* This function will always return a valid pointer, but if an error
* occurred the pattern status will be set to an error. To inspect
* the status of a pattern use cairo_pattern_status().
**/
cairo_pattern_t *
cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
{
cairo_linear_pattern_t *pattern;
pattern = malloc (sizeof (cairo_linear_pattern_t));
if (pattern == NULL)
return NULL;
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_linear_pattern_nil.base;
}
_cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
return &pattern->base.base;
}
/**
* cairo_pattern_create_radial:
* @cx0: x coordinate for the center of the start circle
* @cy0: y coordinate for the center of the start circle
* @radius0: radius of the start cirle
* @cx1: x coordinate for the center of the end circle
* @cy1: y coordinate for the center of the end circle
* @radius1: radius of the end cirle
*
* Creates a new radial gradient cairo_pattern_t between the two
* circles defined by (x0, y0, c0) and (x1, y1, c0). Before using the
* gradient pattern, a number of color stops should be defined using
* cairo_pattern_add_color_stop_rgb() or
* cairo_pattern_add_color_stop_rgba().
*
* Note: The coordinates here are in pattern space. For a new pattern,
* pattern space is identical to user space, but the relationship
* between the spaces can be changed with cairo_pattern_set_matrix().
*
* Return value: the newly created #cairo_pattern_t if succesful, or
* an error pattern in case of no memory. The caller owns the
* returned object and should call cairo_pattern_destroy() when
* finished with it.
*
* This function will always return a valid pointer, but if an error
* occurred the pattern status will be set to an error. To inspect
* the status of a pattern use cairo_pattern_status().
**/
cairo_pattern_t *
cairo_pattern_create_radial (double cx0, double cy0, double radius0,
double cx1, double cy1, double radius1)
@ -258,29 +479,73 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
cairo_radial_pattern_t *pattern;
pattern = malloc (sizeof (cairo_radial_pattern_t));
if (pattern == NULL)
return NULL;
if (pattern == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_radial_pattern_nil.base;
}
_cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
return &pattern->base.base;
}
void
/**
* cairo_pattern_reference:
* @pattern: a #cairo_pattern_t
*
* Increases the reference count on @pattern by one. This prevents
* @pattern from being destroyed until a matching call to
* cairo_pattern_destroy() is made.
*
* Return value: the referenced #cairo_pattern_t.
**/
cairo_pattern_t *
cairo_pattern_reference (cairo_pattern_t *pattern)
{
if (pattern == NULL)
return;
return NULL;
if (pattern->ref_count == (unsigned int)-1)
return pattern;
pattern->ref_count++;
return pattern;
}
/**
* cairo_pattern_status:
* @pattern: a #cairo_pattern_t
*
* Checks whether an error has previously occurred for this
* pattern.
*
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NO_MEMORY, or
* %CAIRO_STATUS_PATTERN_TYPE_MISMATCH.
**/
cairo_status_t
cairo_pattern_status (cairo_pattern_t *pattern)
{
return pattern->status;
}
/**
* cairo_pattern_destroy:
* @pattern: a #cairo_pattern_t
*
* Decreases the reference count on @pattern by one. If the result is
* zero, then @pattern and all associated resources are freed. See
* cairo_pattern_reference().
**/
void
cairo_pattern_destroy (cairo_pattern_t *pattern)
{
if (pattern == NULL)
return;
if (pattern->ref_count == (unsigned int)-1)
return;
pattern->ref_count--;
if (pattern->ref_count)
return;
@ -289,31 +554,51 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
free (pattern);
}
static cairo_status_t
static void
_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
double offset,
cairo_color_t *color)
{
cairo_color_stop_t *stop;
cairo_color_stop_t *new_stops;
pattern->n_stops++;
pattern->stops = realloc (pattern->stops,
pattern->n_stops * sizeof (cairo_color_stop_t));
if (pattern->stops == NULL) {
pattern->n_stops = 0;
return CAIRO_STATUS_NO_MEMORY;
new_stops = realloc (pattern->stops,
pattern->n_stops * sizeof (cairo_color_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];
stop->offset = _cairo_fixed_from_double (offset);
stop->color = *color;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
/**
* cairo_pattern_add_color_stop_rgb:
* @pattern: a #cairo_pattern_t
* @offset: an offset in the range [0.0 .. 1.0]
* @red: red component of color
* @green: green component of color
* @blue: blue component of color
*
* Adds an opaque color stop to a gradient pattern. The offset
* specifies the location along the gradient's control vector. For
* example, a linear gradient's control vector is from (x0,y0) to
* (x1,y1) while a radial gradient's control vector is from any point
* on the start circle to the corresponding point on the end circle.
*
* The color is specified in the same way as in cairo_set_source_rgb().
*
* Note: If the pattern is not a gradient pattern, (eg. a linear or
* radial pattern), then the pattern will be put into an error status
* with a status of CAIRO_STATUS_PATTERN_MISMATCH.
**/
void
cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
double offset,
double red,
@ -322,11 +607,14 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
{
cairo_color_t color;
if (pattern->status)
return;
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
/* XXX: CAIRO_STATUS_INVALID_PATTERN? */
return CAIRO_STATUS_SUCCESS;
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
_cairo_restrict_value (&offset, 0.0, 1.0);
@ -335,12 +623,33 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
_cairo_restrict_value (&blue, 0.0, 1.0);
_cairo_color_init_rgb (&color, red, green, blue);
return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
offset,
&color);
_cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
offset,
&color);
}
cairo_status_t
/**
* cairo_pattern_add_color_stop_rgba:
* @pattern: a #cairo_pattern_t
* @offset: an offset in the range [0.0 .. 1.0]
* @red: red component of color
* @green: green component of color
* @blue: blue component of color
* @alpha: alpha component of color
*
* Adds a translucent color stop to a gradient pattern. The offset
* specifies the location along the gradient's control vector. For
* example, a linear gradient's control vector is from (x0,y0) to
* (x1,y1) while a radial gradient's control vector is from any point
* on the start circle to the corresponding point on the end circle.
*
* The color is specified in the same way as in cairo_set_source_rgba().
*
* Note: If the pattern is not a gradient pattern, (eg. a linear or
* radial pattern), then the pattern will be put into an error status
* with a status of CAIRO_STATUS_PATTERN_MISMATCH.
*/
void
cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
double offset,
double red,
@ -350,11 +659,14 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
{
cairo_color_t color;
if (pattern->status)
return;
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
/* XXX: CAIRO_STATUS_INVALID_PATTERN? */
return CAIRO_STATUS_SUCCESS;
_cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
_cairo_restrict_value (&offset, 0.0, 1.0);
@ -364,34 +676,77 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
_cairo_restrict_value (&alpha, 0.0, 1.0);
_cairo_color_init_rgba (&color, red, green, blue, alpha);
return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
offset,
&color);
_cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
offset,
&color);
}
cairo_status_t
/**
* cairo_pattern_set_matrix:
* @pattern: a #cairo_pattern_t
* @matrix: a #cairo_matrix_t
*
* Sets the pattern's transformation matrix to @matrix. This matrix is
* a transformation from user space to pattern space.
*
* When a pattern is first created it always has the identity matrix
* for its transformation matrix, which means that pattern space is
* initially identical to user space.
*
* Important: Please note that the direction of this transformation
* matrix is from user space to pattern space. This means that if you
* imagine the flow from a pattern to user space (and on to device
* space), then coordinates in that flow will be transformed by the
* inverse of the pattern matrix.
*
* For example, if you want to make a pattern appear twice as large as
* it does by default the correct code to use is:
*
* <informalexample><programlisting>
* cairo_matrix_init_scale (&matrix, 0.5, 0.5);
* cairo_pattern_set_matrix (pattern, &matrix);
* </programlisting></informalexample>
*
* Meanwhile, using values of 2.0 rather than 0.5 in the code above
* would cause the pattern to appear at half of its default size.
*
* Also, please note the discussion of the user-space locking
* semantics of cairo_set_source().
**/
void
cairo_pattern_set_matrix (cairo_pattern_t *pattern,
const cairo_matrix_t *matrix)
{
pattern->matrix = *matrix;
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
return CAIRO_STATUS_SUCCESS;
pattern->matrix = *matrix;
}
cairo_status_t
/**
* cairo_pattern_get_matrix:
* @pattern: a #cairo_pattern_t
* @matrix: return value for the matrix
*
* Stores the pattern's transformation matrix into @matrix.
**/
void
cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
{
*matrix = pattern->matrix;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
void
cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
{
pattern->filter = filter;
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
return CAIRO_STATUS_SUCCESS;
pattern->filter = filter;
}
cairo_filter_t
@ -400,12 +755,15 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
return pattern->filter;
}
cairo_status_t
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
{
pattern->extend = extend;
if (pattern->status) {
_cairo_pattern_set_error (pattern, pattern->status);
return;
}
return CAIRO_STATUS_SUCCESS;
pattern->extend = extend;
}
cairo_extend_t
@ -418,6 +776,8 @@ void
_cairo_pattern_transform (cairo_pattern_t *pattern,
const cairo_matrix_t *ctm_inverse)
{
assert (pattern->status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix);
}
@ -868,8 +1228,9 @@ _cairo_image_data_set_radial (cairo_radial_pattern_t *pattern,
c0_x = y_x + c0_y;
factor = (c0_e - r0) / (c0_x - r0);
} else
} else {
factor = -r0;
}
}
_cairo_pattern_calc_color_at_pixel (&op, factor * 65536, pixels++);
@ -914,7 +1275,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
data = malloc (width * height * 4);
if (!data)
if (data == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
@ -943,7 +1304,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
width, height,
width * 4);
if (image == NULL) {
if (image->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
@ -960,7 +1321,6 @@ _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;
attr->clip_saved = FALSE;
return status;
}
@ -976,11 +1336,10 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
cairo_surface_attributes_t *attribs)
{
*out = _cairo_surface_create_similar_solid (dst,
CAIRO_FORMAT_ARGB32,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
&pattern->color);
if (*out == NULL)
if ((*out)->status)
return CAIRO_STATUS_NO_MEMORY;
attribs->x_offset = attribs->y_offset = 0;
@ -988,7 +1347,6 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
attribs->extend = CAIRO_EXTEND_REPEAT;
attribs->filter = CAIRO_FILTER_NEAREST;
attribs->acquired = FALSE;
attribs->clip_saved = FALSE;
return CAIRO_STATUS_SUCCESS;
}
@ -1015,7 +1373,7 @@ _cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern)
solid = (cairo_solid_pattern_t *) pattern;
return (solid->color.alpha >= ((double)0xff00 / (double)0xffff));
return CAIRO_ALPHA_IS_OPAQUE (solid->color.alpha);
}
static cairo_int_status_t
@ -1032,35 +1390,23 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
int tx, ty;
attr->acquired = FALSE;
attr->clip_saved = FALSE;
if (_cairo_surface_is_image (dst))
{
cairo_image_surface_t *image;
status = _cairo_surface_begin_reset_clip (pattern->surface);
if (!CAIRO_OK (status))
return status;
status = _cairo_surface_acquire_source_image (pattern->surface,
&image,
&attr->extra);
if (!CAIRO_OK (status))
if (status)
return status;
_cairo_surface_end (pattern->surface);
*out = &image->base;
attr->acquired = TRUE;
}
else
{
status = _cairo_surface_begin_reset_clip (pattern->surface);
if (!CAIRO_OK (status))
return status;
status = _cairo_surface_clone_similar (dst, pattern->surface, out);
_cairo_surface_end (pattern->surface);
}
attr->extend = pattern->base.extend;
@ -1111,6 +1457,9 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
{
cairo_status_t status;
if (pattern->status)
return pattern->status;
switch (pattern->type) {
case CAIRO_PATTERN_SOLID: {
cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) pattern;
@ -1144,11 +1493,13 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
attributes);
}
else
{
status = _cairo_pattern_acquire_surface_for_gradient (src, dst,
x, y,
width, height,
surface_out,
attributes);
}
} break;
case CAIRO_PATTERN_SURFACE: {
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
@ -1162,43 +1513,37 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
status = CAIRO_INT_STATUS_UNSUPPORTED;
}
if (CAIRO_OK (status) && (*surface_out)->clip_region) {
status = _cairo_surface_begin_reset_clip (*surface_out);
if (!CAIRO_OK (status)) {
_cairo_pattern_release_surface (dst, *surface_out, attributes);
return status;
}
attributes->clip_saved = TRUE;
}
return status;
}
/**
* _cairo_pattern_release_surface:
* @pattern: a #cairo_pattern_t
* @info: pointer to #cairo_surface_attributes_t filled in by
* _cairo_pattern_acquire_surface
* @surface: a surface obtained by _cairo_pattern_acquire_surface
* @attributes: attributes obtained by _cairo_pattern_acquire_surface
*
* Releases resources obtained by _cairo_pattern_acquire_surface.
**/
void
_cairo_pattern_release_surface (cairo_surface_t *dst,
_cairo_pattern_release_surface (cairo_pattern_t *pattern,
cairo_surface_t *surface,
cairo_surface_attributes_t *attributes)
{
if (attributes->clip_saved)
_cairo_surface_end (surface);
if (attributes->acquired)
{
_cairo_surface_release_source_image (dst,
cairo_surface_pattern_t *surface_pattern;
assert (pattern->type == CAIRO_PATTERN_SURFACE);
surface_pattern = (cairo_surface_pattern_t *) pattern;
_cairo_surface_release_source_image (surface_pattern->surface,
(cairo_image_surface_t *) surface,
attributes->extra);
} else
}
else
{
cairo_surface_destroy (surface);
}
}
cairo_int_status_t
@ -1217,7 +1562,12 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
cairo_surface_attributes_t *mask_attributes)
{
cairo_int_status_t status;
cairo_pattern_union_t tmp;
cairo_pattern_union_t src_tmp, mask_tmp;
if (src->status)
return src->status;
if (mask && mask->status)
return mask->status;
/* If src and mask are both solid, then the mask alpha can be
* combined into src and mask can be ignored. */
@ -1227,7 +1577,7 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
* support RENDER-style 4-channel masks. */
if (src->type == CAIRO_PATTERN_SOLID &&
mask && mask->type == CAIRO_PATTERN_SOLID)
{
{
cairo_color_t combined;
cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
cairo_solid_pattern_t *mask_solid = (cairo_solid_pattern_t *) mask;
@ -1235,44 +1585,44 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
combined = src_solid->color;
_cairo_color_multiply_alpha (&combined, mask_solid->color.alpha);
_cairo_pattern_init_solid (&tmp.solid, &combined);
_cairo_pattern_init_solid (&src_tmp.solid, &combined);
mask = NULL;
} else {
_cairo_pattern_init_copy (&tmp.base, src);
}
status = _cairo_pattern_acquire_surface (&tmp.base, dst,
src_x, src_y,
width, height,
src_out, src_attributes);
_cairo_pattern_fini (&tmp.base);
if (status)
return status;
if (mask)
{
_cairo_pattern_init_copy (&tmp.base, mask);
status = _cairo_pattern_acquire_surface (&tmp.base, dst,
mask_x, mask_y,
width, height,
mask_out, mask_attributes);
_cairo_pattern_fini (&tmp.base);
if (status)
{
_cairo_pattern_release_surface (dst, *src_out, src_attributes);
return status;
}
}
else
{
*mask_out = NULL;
_cairo_pattern_init_copy (&src_tmp.base, src);
}
return CAIRO_STATUS_SUCCESS;
status = _cairo_pattern_acquire_surface (&src_tmp.base, dst,
src_x, src_y,
width, height,
src_out, src_attributes);
if (status) {
_cairo_pattern_fini (&src_tmp.base);
return status;
}
if (mask == NULL)
{
_cairo_pattern_fini (&src_tmp.base);
*mask_out = NULL;
return CAIRO_STATUS_SUCCESS;
}
_cairo_pattern_init_copy (&mask_tmp.base, mask);
status = _cairo_pattern_acquire_surface (&mask_tmp.base, dst,
mask_x, mask_y,
width, height,
mask_out, mask_attributes);
if (status)
_cairo_pattern_release_surface (&src_tmp.base,
*src_out, src_attributes);
_cairo_pattern_fini (&src_tmp.base);
_cairo_pattern_fini (&mask_tmp.base);
return status;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_PDF_SURFACE
#if CAIRO_HAS_PDF_SURFACE
CAIRO_BEGIN_DECLS

Просмотреть файл

@ -306,36 +306,36 @@ an ellipse parameterized by angle 't':
Perturb t by ± d and compute two new points (x+,y+), (x-,y-).
The distance from the average of these two points to (x,y) represents
the maximum error in approximating the ellipse with a polygon formed
from vertices 2? radians apart.
from vertices 2 radians apart.
x+ = M cos (t+?) y+ = m sin (t+?)
x- = M cos (t-?) y- = m sin (t-?)
x+ = M cos (t+) y+ = m sin (t+)
x- = M cos (t-) y- = m sin (t-)
Now compute the approximation error, E:
Ex = (x - (x+ + x-) / 2)
Ex = (M cos(t) - (Mcos(t+?) + Mcos(t-?))/2)
= M (cos(t) - (cos(t)cos(?) + sin(t)sin(?) +
cos(t)cos(?) - sin(t)sin(?))/2)
= M(cos(t) - cos(t)cos(?))
= M cos(t) (1 - cos(?))
Ex = (M cos(t) - (Mcos(t+) + Mcos(t-))/2)
= M (cos(t) - (cos(t)cos() + sin(t)sin() +
cos(t)cos() - sin(t)sin())/2)
= M(cos(t) - cos(t)cos())
= M cos(t) (1 - cos())
Ey = y - (y+ - y-) / 2
= m sin (t) - (m sin(t+?) + m sin(t-?)) / 2
= m (sin(t) - (sin(t)cos(?) + cos(t)sin(?) +
sin(t)cos(?) - cos(t)sin(?))/2)
= m (sin(t) - sin(t)cos(?))
= m sin(t) (1 - cos(?))
= m sin (t) - (m sin(t+) + m sin(t-)) / 2
= m (sin(t) - (sin(t)cos() + cos(t)sin() +
sin(t)cos() - cos(t)sin())/2)
= m (sin(t) - sin(t)cos())
= m sin(t) (1 - cos())
E² = Ex² + Ey²
= (M cos(t) (1 - cos (?)))² + (m sin(t) (1-cos(?)))²
= (1 - cos(?))² (M² cos²(t) + m² sin²(t))
= (1 - cos(?))² ((m² + M² - m²) cos² (t) + m² sin²(t))
= (1 - cos(?))² (M² - m²) cos² (t) + (1 - cos(?))² m²
= (M cos(t) (1 - cos ()))² + (m sin(t) (1-cos()))²
= (1 - cos())² (M² cos²(t) + m² sin²(t))
= (1 - cos())² ((m² + M² - m²) cos² (t) + m² sin²(t))
= (1 - cos())² (M² - m²) cos² (t) + (1 - cos())² m²
Find the extremum by differentiation wrt t and setting that to zero
(E²)/(t) = (1-cos(?))² (M² - m²) (-2 cos(t) sin(t))
(E²)/(t) = (1-cos())² (M² - m²) (-2 cos(t) sin(t))
0 = 2 cos (t) sin (t)
0 = sin (2t)
@ -344,25 +344,25 @@ Find the extremum by differentiation wrt t and setting that to zero
Which is to say that the maximum and minimum errors occur on the
axes of the ellipse at 0 and π radians:
E²(0) = (1-cos(?))² (M² - m²) + (1-cos(?))² m²
= (1-cos(?))² M²
E²(π) = (1-cos(?))² m²
E²(0) = (1-cos())² (M² - m²) + (1-cos())² m²
= (1-cos())² M²
E²(π) = (1-cos())² m²
maximum error = M (1-cos(?))
minimum error = m (1-cos(?))
maximum error = M (1-cos())
minimum error = m (1-cos())
We must make maximum error tolerance, so compute the ? needed:
We must make maximum error tolerance, so compute the needed:
tolerance = M (1-cos(?))
tolerance / M = 1 - cos (?)
cos(?) = 1 - tolerance/M
? = acos (1 - tolerance / M);
tolerance = M (1-cos())
tolerance / M = 1 - cos ()
cos() = 1 - tolerance/M
= acos (1 - tolerance / M);
Remembering that ? is half of our angle between vertices,
Remembering that is half of our angle between vertices,
the number of vertices is then
vertices = ceil(2π/2?).
= ceil(π/?).
vertices = ceil(2π/2).
= ceil(π/).
Note that this also equation works for M == m (a circle) as it
doesn't matter where on the circle the error is computed.
@ -374,15 +374,32 @@ _cairo_pen_vertices_needed (double tolerance,
double radius,
cairo_matrix_t *matrix)
{
double min, max, major_axis;
int num_vertices;
double a = matrix->xx, b = matrix->yx;
double c = matrix->xy, d = matrix->yy;
_cairo_matrix_compute_expansion_factors (matrix, &min, &max);
major_axis = radius * max;
double i = a*a + c*c;
double j = b*b + d*d;
double f = 0.5 * (i + j);
double g = 0.5 * (i - j);
double h = a*b + c*d;
/*
* compute major and minor axes lengths for
* a pen with the specified radius
*/
double major_axis = radius * sqrt (f + sqrt (g*g+h*h));
/*
* we don't need the minor axis length, which is
* double min = radius * sqrt (f - sqrt (g*g+h*h));
*/
/*
* compute number of vertices needed
*/
int num_vertices;
/* Where tolerance / M is > 1, we use 4 points */
if (tolerance >= major_axis) {

Просмотреть файл

@ -36,8 +36,10 @@
*/
#include <png.h>
#include <errno.h>
#include "cairoint.h"
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
static void
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
{
@ -53,14 +55,33 @@ unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
if (alpha == 0) {
b[0] = b[1] = b[2] = b[3] = 0;
} else {
b[0] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
b[2] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
/* Converts native endian xRGB => RGBx bytes */
static void
convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
{
int i;
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *b = &data[i];
uint32_t pixel;
memcpy (&pixel, b, sizeof (uint32_t));
b[0] = (pixel & 0xff0000) >> 16;
b[1] = (pixel & 0x00ff00) >> 8;
b[2] = (pixel & 0x0000ff) >> 0;
b[3] = 0;
}
}
static cairo_status_t
write_png (cairo_surface_t *surface,
png_rw_ptr write_func,
@ -153,14 +174,19 @@ write_png (cairo_surface_t *surface,
png_convert_from_time_t (&pt, time (NULL));
png_set_tIME (png, info, &pt);
png_set_write_user_transform_fn (png, unpremultiply_data);
if (image->format == CAIRO_FORMAT_ARGB32 ||
image->format == CAIRO_FORMAT_RGB24)
png_set_bgr (png);
/* We have to call png_write_info() before setting up the write
* transformation, since it stores data internally in 'png'
* that is needed for the write transformation functions to work.
*/
png_write_info (png, info);
if (image->format == CAIRO_FORMAT_ARGB32)
png_set_write_user_transform_fn (png, unpremultiply_data);
else if (image->format == CAIRO_FORMAT_RGB24)
png_set_write_user_transform_fn (png, convert_data_to_bytes);
if (image->format == CAIRO_FORMAT_RGB24)
png_set_filler (png, 0, PNG_FILLER_AFTER);
png_write_info (png, info);
png_write_image (png, rows);
png_write_end (png, info);
@ -212,7 +238,7 @@ cairo_surface_write_to_png (cairo_surface_t *surface,
status = write_png (surface, stdio_write_func, fp);
if (fclose (fp) && CAIRO_OK (status))
if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
status = CAIRO_STATUS_WRITE_ERROR;
return status;
@ -226,10 +252,12 @@ struct png_write_closure_t {
static void
stream_write_func (png_structp png, png_bytep data, png_size_t size)
{
cairo_status_t status;
struct png_write_closure_t *png_closure;
png_closure = png_get_io_ptr (png);
if (!CAIRO_OK (png_closure->write_func (png_closure->closure, data, size)))
status = png_closure->write_func (png_closure->closure, data, size);
if (status)
png_error(png, "Write Error");
}
@ -260,6 +288,7 @@ cairo_surface_write_to_png_stream (cairo_surface_t *surface,
return write_png (surface, stream_write_func, &png_closure);
}
/* Premultiplies data and converts RGBA bytes => native endian */
static void
premultiply_data (png_structp png,
png_row_infop row_info,
@ -269,9 +298,9 @@ premultiply_data (png_structp png,
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t *base = &data[i];
uint8_t blue = base[0];
uint8_t red = base[0];
uint8_t green = base[1];
uint8_t red = base[2];
uint8_t blue = base[2];
uint8_t alpha = base[3];
uint32_t p;
@ -287,19 +316,15 @@ static cairo_surface_t *
read_png (png_rw_ptr read_func,
void *closure)
{
cairo_surface_t *surface;
png_byte *data;
cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil;
png_byte *data = NULL;
int i;
png_struct *png;
png_struct *png = NULL;
png_info *info;
png_uint_32 png_width, png_height, stride;
int depth, color_type, interlace;
unsigned int pixel_size;
png_byte **row_pointers;
surface = NULL;
data = NULL;
row_pointers = NULL;
png_byte **row_pointers = NULL;
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
@ -307,7 +332,7 @@ read_png (png_rw_ptr read_func,
NULL,
NULL);
if (png == NULL)
return NULL;
goto BAIL;
info = png_create_info_struct (png);
if (info == NULL)
@ -315,8 +340,10 @@ read_png (png_rw_ptr read_func,
png_set_read_fn (png, closure, read_func);
if (setjmp (png_jmpbuf (png)))
if (setjmp (png_jmpbuf (png))) {
surface = (cairo_surface_t*) &_cairo_surface_nil_read_error;
goto BAIL;
}
png_read_info (png, info);
@ -350,7 +377,6 @@ read_png (png_rw_ptr read_func,
if (interlace != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
png_set_bgr (png);
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
png_set_read_user_transform_fn (png, premultiply_data);
@ -375,13 +401,22 @@ read_png (png_rw_ptr read_func,
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
png_width, png_height, stride);
if (surface->status)
goto BAIL;
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
data = NULL;
BAIL:
free (row_pointers);
free (data);
png_destroy_read_struct (&png, NULL, NULL);
if (row_pointers)
free (row_pointers);
if (data)
free (data);
if (png)
png_destroy_read_struct (&png, &info, NULL);
if (surface->status)
_cairo_error (surface->status);
return surface;
}
@ -404,8 +439,13 @@ stdio_read_func (png_structp png, png_bytep data, png_size_t size)
* given PNG file.
*
* Return value: a new #cairo_surface_t initialized with the contents
* of the PNG file or %NULL if the file is not a valid PNG file or
* memory could not be allocated for the operation.
* of the PNG file, or a "nil" surface if any error occurred. A nil
* surface can be checked for with cairo_surface_status(surface) which
* may return one of the following values:
*
* CAIRO_STATUS_NO_MEMORY
* CAIRO_STATUS_FILE_NOT_FOUND
* CAIRO_STATUS_READ_ERROR
**/
cairo_surface_t *
cairo_image_surface_create_from_png (const char *filename)
@ -414,8 +454,19 @@ cairo_image_surface_create_from_png (const char *filename)
cairo_surface_t *surface;
fp = fopen (filename, "rb");
if (fp == NULL)
return NULL;
if (fp == NULL) {
switch (errno) {
case ENOMEM:
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
case ENOENT:
_cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
return (cairo_surface_t*) &_cairo_surface_nil_file_not_found;
default:
_cairo_error (CAIRO_STATUS_READ_ERROR);
return (cairo_surface_t*) &_cairo_surface_nil_read_error;
}
}
surface = read_png (stdio_read_func, fp);
@ -432,10 +483,12 @@ struct png_read_closure_t {
static void
stream_read_func (png_structp png, png_bytep data, png_size_t size)
{
cairo_status_t status;
struct png_read_closure_t *png_closure;
png_closure = png_get_io_ptr (png);
if (!CAIRO_OK (png_closure->read_func (png_closure->closure, data, size)))
status = png_closure->read_func (png_closure->closure, data, size);
if (status)
png_error(png, "Read Error");
}
@ -460,6 +513,6 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
png_closure.read_func = read_func;
png_closure.closure = closure;
return read_png (stream_read_func, &closure);
return read_png (stream_read_func, &png_closure);
}

Просмотреть файл

@ -42,10 +42,11 @@
struct _cairo {
unsigned int ref_count;
cairo_gstate_t *gstate;
cairo_status_t status;
cairo_path_fixed_t path;
cairo_status_t status;
cairo_gstate_t *gstate;
};
#endif /* CAIRO_PRIVATE_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_PS_SURFACE
#if CAIRO_HAS_PS_SURFACE
#include <stdio.h>

Просмотреть файл

@ -58,17 +58,6 @@ ImageDataReleaseFunc(void *info, const void *data, size_t size)
}
}
static cairo_surface_t *_cairo_quartz_surface_create_similar(void
*abstract_src,
cairo_format_t
format,
int drawable,
int width,
int height)
{
return NULL;
}
static cairo_status_t
_cairo_quartz_surface_finish(void *abstract_surface)
{
@ -135,12 +124,11 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
CAIRO_FORMAT_ARGB32,
surface->width,
surface->height, rowBytes);
// Set the image surface Cairo state to match our own.
_cairo_image_surface_set_repeat(surface->image, surface->base.repeat);
_cairo_image_surface_set_matrix(surface->image,
&(surface->base.matrix));
if (surface->image->base.status) {
/* XXX: I assume we're leaking memory here, but I don't know
* the right call to use to clean up from CGImageCreate. */
return CAIRO_STATUS_NO_MEMORY;
}
*image_out = surface->image;
*image_extra = NULL;
@ -164,6 +152,8 @@ _cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
image_rect->height = surface->image->height;
*image_out = surface->image;
if (image_extra)
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -195,8 +185,11 @@ _cairo_quartz_surface_set_clip_region(void *abstract_surface,
pixman_region16_t * region)
{
cairo_quartz_surface_t *surface = abstract_surface;
unsigned int serial;
return _cairo_surface_set_clip_region(&surface->image->base, region);
serial = _cairo_surface_allocate_clip_serial (&surface->image->base);
return _cairo_surface_set_clip_region(&surface->image->base,
region, serial);
}
static cairo_int_status_t
@ -214,7 +207,7 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
}
static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
_cairo_quartz_surface_create_similar,
NULL, /* create_similar */
_cairo_quartz_surface_finish,
_cairo_quartz_surface_acquire_source_image,
NULL, /* release_source_image */
@ -227,6 +220,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
NULL, /* copy_page */
NULL, /* show_page */
_cairo_quartz_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_quartz_surface_get_extents,
NULL /* show_glyphs */
};
@ -238,8 +232,10 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
cairo_quartz_surface_t *surface;
surface = malloc(sizeof(cairo_quartz_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);

Просмотреть файл

@ -39,16 +39,16 @@
#include <cairo.h>
#ifdef CAIRO_HAS_QUARTZ_SURFACE
#if CAIRO_HAS_QUARTZ_SURFACE
#include <Carbon/Carbon.h>
CAIRO_BEGIN_DECLS
cairo_surface_t *
cairo_quartz_surface_create ( CGContextRef context,
int width,
int height);
cairo_quartz_surface_create (CGContextRef context,
int width,
int height);
CAIRO_END_DECLS

Просмотреть файл

@ -0,0 +1,83 @@
/* 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):
* Owen Taylor <otaylor@redhat.com>
*/
#include <cairoint.h>
/**
* _cairo_region_create_from_rectangle:
* @rect: a #cairo_rectangle_t
*
* Creates a region with extents initialized from the given
* rectangle.
*
* Return value: a newly created #pixman_region16_t or %NULL if
* memory couldn't a allocated.
**/
pixman_region16_t *
_cairo_region_create_from_rectangle (cairo_rectangle_t *rect)
{
/* We can't use pixman_region_create_simple(), because it doesn't
* have an error return
*/
pixman_region16_t *region = pixman_region_create ();
if (pixman_region_union_rect (region, region,
rect->x, rect->y,
rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) {
pixman_region_destroy (region);
return NULL;
}
return region;
}
/**
* _cairo_region_extents_rectangle:
* @region: a #pixman_region16_t
* @rect: rectangle into which to store the extents
*
* Gets the bounding box of a region as a cairo_rectangle_t
**/
void
_cairo_region_extents_rectangle (pixman_region16_t *region,
cairo_rectangle_t *rect)
{
pixman_box16_t *region_extents = pixman_region_extents (region);
rect->x = region_extents->x1;
rect->y = region_extents->y1;
rect->width = region_extents->x2 - region_extents->x1;
rect->height = region_extents->y2 - region_extents->y1;
}

Просмотреть файл

@ -64,23 +64,21 @@ _cairo_spline_init (cairo_spline_t *spline,
spline->c = *c;
spline->d = *d;
if (a->x != b->x || a->y != b->y) {
if (a->x != b->x || a->y != b->y)
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->b);
} else if (a->x != c->x || a->y != c->y) {
else if (a->x != c->x || a->y != c->y)
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->c);
} else if (a->x != d->x || a->y != d->y) {
else if (a->x != d->x || a->y != d->y)
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->d);
} else {
else
return CAIRO_INT_STATUS_DEGENERATE;
}
if (c->x != d->x || c->y != d->y) {
if (c->x != d->x || c->y != d->y)
_cairo_slope_init (&spline->final_slope, &spline->c, &spline->d);
} else if (b->x != d->x || b->y != d->y) {
else if (b->x != d->x || b->y != d->y)
_cairo_slope_init (&spline->final_slope, &spline->b, &spline->d);
} else {
else
_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
}
spline->num_points = 0;
spline->points_size = 0;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -229,6 +229,35 @@ _compare_point_fixed_by_y (const void *av, const void *bv)
return ret;
}
void
_cairo_traps_translate (cairo_traps_t *traps, int x, int y)
{
cairo_fixed_t xoff, yoff;
cairo_trapezoid_t *t;
int i;
/* Ugh. The cairo_composite/(Render) interface doesn't allow
an offset for the trapezoids. Need to manually shift all
the coordinates to align with the offset origin of the
intermediate surface. */
xoff = _cairo_fixed_from_int (x);
yoff = _cairo_fixed_from_int (y);
for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) {
t->top += yoff;
t->bottom += yoff;
t->left.p1.x += xoff;
t->left.p1.y += yoff;
t->left.p2.x += xoff;
t->left.p2.y += yoff;
t->right.p1.x += xoff;
t->right.p1.y += yoff;
t->right.p2.x += xoff;
t->right.p2.y += yoff;
}
}
cairo_status_t
_cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
{
@ -820,7 +849,7 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
int width = _cairo_fixed_integer_part(traps->traps[i].right.p1.x) - x;
int height = _cairo_fixed_integer_part(traps->traps[i].left.p2.y) - y;
/* Sometimes we get degenerate trapezoids from the tesellator,
/* XXX: Sometimes we get degenerate trapezoids from the tesellator,
* if we call pixman_region_union_rect(), it bizarrly fails on such
* an empty rectangle, so skip them.
*/

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: cairo-wideint.c,v 1.1 2005/06/04 07:03:27 vladimir%pobox.com Exp $
* $Id: cairo-wideint.c,v 1.6 2006/02/03 04:49:23 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
@ -36,22 +36,6 @@
#include "cairoint.h"
#if !HAVE_UINT64_T || !HAVE_UINT128_T
static const unsigned char top_bit[256] =
{
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
#endif
#if HAVE_UINT64_T
#define _cairo_uint32s_to_uint64(h,l) ((uint64_t) (h) << 32 | (l))
@ -157,7 +141,8 @@ _cairo_uint32x32_64_mul (uint32_t a, uint32_t b)
cairo_int64_t
_cairo_int32x32_64_mul (int32_t a, int32_t b)
{
s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t b));
cairo_int64_t s;
s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t) b);
if (a < 0)
s.hi -= b;
if (b < 0)
@ -270,198 +255,38 @@ _cairo_uint64_negate (cairo_uint64_t a)
}
/*
* The design of this algorithm comes from GCC,
* but the actual implementation is new
* Simple bit-at-a-time divide.
*/
static const int
_cairo_leading_zeros32 (uint32_t i)
{
int top;
if (i < 0x100)
top = 0;
else if (i < 0x10000)
top = 8;
else if (i < 0x1000000)
top = 16;
else
top = 24;
top = top + top_bit [i >> top];
return 32 - top;
}
typedef struct _cairo_uquorem32_t {
uint32_t quo;
uint32_t rem;
} cairo_uquorem32_t;
/*
* den >= num.hi
*/
static const cairo_uquorem32_t
_cairo_uint64x32_normalized_divrem (cairo_uint64_t num, uint32_t den)
{
cairo_uquorem32_t qr;
uint32_t q0, q1, r0, r1;
uint16_t d0, d1;
uint32_t t;
d0 = den & 0xffff;
d1 = den >> 16;
q1 = num.hi / d1;
r1 = num.hi % d1;
t = q1 * d0;
r1 = (r1 << 16) | (num.lo >> 16);
if (r1 < t)
{
q1--;
r1 += den;
if (r1 >= den && r1 < t)
{
q1--;
r1 += den;
}
}
r1 -= t;
q0 = r1 / d1;
r0 = r1 % d1;
t = q0 * d0;
r0 = (r0 << 16) | (num.lo & 0xffff);
if (r0 < t)
{
q0--;
r0 += den;
if (r0 >= den && r0 < t)
{
q0--;
r0 += den;
}
}
r0 -= t;
qr.quo = (q1 << 16) | q0;
qr.rem = r0;
return qr;
}
cairo_uquorem64_t
_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den)
{
cairo_uquorem32_t qr32;
cairo_uquorem64_t qr;
int norm;
uint32_t q1, q0, r1, r0;
if (den.hi == 0)
cairo_uint64_t bit;
cairo_uint64_t quo;
bit = _cairo_uint32_to_uint64 (1);
/* normalize to make den >= num, but not overflow */
while (_cairo_uint64_lt (den, num) && (den.hi & 0x80000000) == 0)
{
if (den.lo > num.hi)
{
/* 0q = nn / 0d */
norm = _cairo_leading_zeros32 (den.lo);
if (norm)
{
den.lo <<= norm;
num = _cairo_uint64_lsl (num, norm);
}
q1 = 0;
}
else
{
/* qq = NN / 0d */
if (den.lo == 0)
den.lo = 1 / den.lo;
norm = _cairo_leading_zeros32 (den.lo);
if (norm)
{
cairo_uint64_t num1;
den.lo <<= norm;
num1 = _cairo_uint64_rsl (num, 32 - norm);
qr32 = _cairo_uint64x32_normalized_divrem (num1, den.lo);
q1 = qr32.quo;
num.hi = qr32.rem;
num.lo <<= norm;
}
else
{
num.hi -= den.lo;
q1 = 1;
}
}
qr32 = _cairo_uint64x32_normalized_divrem (num, den.lo);
q0 = qr32.quo;
r1 = 0;
r0 = qr32.rem >> norm;
bit = _cairo_uint64_lsl (bit, 1);
den = _cairo_uint64_lsl (den, 1);
}
else
quo = _cairo_uint32_to_uint64 (0);
/* generate quotient, one bit at a time */
while (bit.hi | bit.lo)
{
if (den.hi > num.hi)
if (_cairo_uint64_le (den, num))
{
/* 00 = nn / DD */
q0 = q1 = 0;
r0 = num.lo;
r1 = num.hi;
}
else
{
/* 0q = NN / dd */
norm = _cairo_leading_zeros32 (den.hi);
if (norm == 0)
{
if (num.hi > den.hi || num.lo >= den.lo)
{
q0 = 1;
num = _cairo_uint64_sub (num, den);
}
else
q0 = 0;
q1 = 0;
r0 = num.lo;
r1 = num.hi;
}
else
{
cairo_uint64_t num1;
cairo_uint64_t part;
num1 = _cairo_uint64_rsl (num, 32 - norm);
den = _cairo_uint64_lsl (den, norm);
qr32 = _cairo_uint64x32_normalized_divrem (num1, den.hi);
part = _cairo_uint32x32_64_mul (qr32.quo, den.lo);
q0 = qr32.quo;
num.lo <<= norm;
num.hi = qr32.rem;
if (_cairo_uint64_gt (part, num))
{
q0--;
part = _cairo_uint64_sub (part, den);
}
q1 = 0;
num = _cairo_uint64_sub (num, part);
num = _cairo_uint64_rsl (num, norm);
r0 = num.lo;
r1 = num.hi;
}
num = _cairo_uint64_sub (num, den);
quo = _cairo_uint64_add (quo, bit);
}
bit = _cairo_uint64_rsl (bit, 1);
den = _cairo_uint64_rsl (den, 1);
}
qr.quo.lo = q0;
qr.quo.hi = q1;
qr.rem.lo = r0;
qr.rem.hi = r1;
qr.quo = quo;
qr.rem = num;
return qr;
}
@ -752,232 +577,42 @@ _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b)
_cairo_uint64_eq (a.lo, b.lo));
}
/*
* The design of this algorithm comes from GCC,
* but the actual implementation is new
*/
/*
* den >= num.hi
*/
static cairo_uquorem64_t
_cairo_uint128x64_normalized_divrem (cairo_uint128_t num, cairo_uint64_t den)
{
cairo_uquorem64_t qr64;
cairo_uquorem64_t qr;
uint32_t q0, q1;
cairo_uint64_t r0, r1;
uint32_t d0, d1;
cairo_uint64_t t;
d0 = uint64_lo32 (den);
d1 = uint64_hi32 (den);
qr64 = _cairo_uint64_divrem (num.hi, _cairo_uint32_to_uint64 (d1));
q1 = _cairo_uint64_to_uint32 (qr64.quo);
r1 = qr64.rem;
t = _cairo_uint32x32_64_mul (q1, d0);
r1 = _cairo_uint64_add (_cairo_uint64_lsl (r1, 32),
_cairo_uint64_rsl (num.lo, 32));
if (_cairo_uint64_lt (r1, t))
{
q1--;
r1 = _cairo_uint64_add (r1, den);
if (_cairo_uint64_ge (r1, den) && _cairo_uint64_lt (r1, t))
{
q1--;
r1 = _cairo_uint64_add (r1, den);
}
}
r1 = _cairo_uint64_sub (r1, t);
qr64 = _cairo_uint64_divrem (r1, _cairo_uint32_to_uint64 (d1));
q0 = _cairo_uint64_to_uint32 (qr64.quo);
r0 = qr64.rem;
t = _cairo_uint32x32_64_mul (q0, d0);
r0 = _cairo_uint64_add (_cairo_uint64_lsl (r0, 32),
_cairo_uint32_to_uint64 (_cairo_uint64_to_uint32 (num.lo)));
if (_cairo_uint64_lt (r0, t))
{
q0--;
r0 = _cairo_uint64_add (r0, den);
if (_cairo_uint64_ge (r0, den) && _cairo_uint64_lt (r0, t))
{
q0--;
r0 = _cairo_uint64_add (r0, den);
}
}
r0 = _cairo_uint64_sub (r0, t);
qr.quo = _cairo_uint32s_to_uint64 (q1, q0);
qr.rem = r0;
return qr;
}
#if HAVE_UINT64_T
static int
_cairo_leading_zeros64 (cairo_uint64_t q)
{
int top = 0;
if (q >= (uint64_t) 0x10000 << 16)
{
top += 32;
q >>= 32;
}
if (q >= (uint64_t) 0x10000)
{
top += 16;
q >>= 16;
}
if (q >= (uint64_t) 0x100)
{
top += 8;
q >>= 8;
}
top += top_bit [q];
return 64 - top;
}
#define _cairo_msbset64(q) (q & ((uint64_t) 1 << 63))
#else
static const int
_cairo_leading_zeros64 (cairo_uint64_t d)
{
if (d.hi)
return _cairo_leading_zeros32 (d.hi);
else
return 32 + _cairo_leading_zeros32 (d.lo);
}
#define _cairo_msbset64(q) (q.hi & ((uint32_t) 1 << 31))
#endif
cairo_uquorem128_t
_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den)
{
cairo_uquorem64_t qr64;
cairo_uquorem128_t qr;
int norm;
cairo_uint64_t q1, q0, r1, r0;
if (_cairo_uint64_eq (den.hi, _cairo_uint32_to_uint64 (0)))
cairo_uint128_t bit;
cairo_uint128_t quo;
bit = _cairo_uint32_to_uint128 (1);
/* normalize to make den >= num, but not overflow */
while (_cairo_uint128_lt (den, num) && !_cairo_msbset64(den.hi))
{
if (_cairo_uint64_gt (den.lo, num.hi))
{
/* 0q = nn / 0d */
norm = _cairo_leading_zeros64 (den.lo);
if (norm)
{
den.lo = _cairo_uint64_lsl (den.lo, norm);
num = _cairo_uint128_lsl (num, norm);
}
q1 = _cairo_uint32_to_uint64 (0);
}
else
{
/* qq = NN / 0d */
if (_cairo_uint64_eq (den.lo, _cairo_uint32_to_uint64 (0)))
den.lo = _cairo_uint64_divrem (_cairo_uint32_to_uint64 (1),
den.lo).quo;
norm = _cairo_leading_zeros64 (den.lo);
if (norm)
{
cairo_uint128_t num1;
den.lo = _cairo_uint64_lsl (den.lo, norm);
num1 = _cairo_uint128_rsl (num, 64 - norm);
qr64 = _cairo_uint128x64_normalized_divrem (num1, den.lo);
q1 = qr64.quo;
num.hi = qr64.rem;
num.lo = _cairo_uint64_lsl (num.lo, norm);
}
else
{
num.hi = _cairo_uint64_sub (num.hi, den.lo);
q1 = _cairo_uint32_to_uint64 (1);
}
}
qr64 = _cairo_uint128x64_normalized_divrem (num, den.lo);
q0 = qr64.quo;
r1 = _cairo_uint32_to_uint64 (0);
r0 = _cairo_uint64_rsl (qr64.rem, norm);
bit = _cairo_uint128_lsl (bit, 1);
den = _cairo_uint128_lsl (den, 1);
}
else
quo = _cairo_uint32_to_uint128 (0);
/* generate quotient, one bit at a time */
while (_cairo_uint128_ne (bit, _cairo_uint32_to_uint128(0)))
{
if (_cairo_uint64_gt (den.hi, num.hi))
if (_cairo_uint128_le (den, num))
{
/* 00 = nn / DD */
q0 = q1 = _cairo_uint32_to_uint64 (0);
r0 = num.lo;
r1 = num.hi;
}
else
{
/* 0q = NN / dd */
norm = _cairo_leading_zeros64 (den.hi);
if (norm == 0)
{
if (_cairo_uint64_gt (num.hi, den.hi) ||
_cairo_uint64_ge (num.lo, den.lo))
{
q0 = _cairo_uint32_to_uint64 (1);
num = _cairo_uint128_sub (num, den);
}
else
q0 = _cairo_uint32_to_uint64 (0);
q1 = _cairo_uint32_to_uint64 (0);
r0 = num.lo;
r1 = num.hi;
}
else
{
cairo_uint128_t num1;
cairo_uint128_t part;
num1 = _cairo_uint128_rsl (num, 64 - norm);
den = _cairo_uint128_lsl (den, norm);
qr64 = _cairo_uint128x64_normalized_divrem (num1, den.hi);
part = _cairo_uint64x64_128_mul (qr64.quo, den.lo);
q0 = qr64.quo;
num.lo = _cairo_uint64_lsl (num.lo, norm);
num.hi = qr64.rem;
if (_cairo_uint128_gt (part, num))
{
q0 = _cairo_uint64_sub (q0, _cairo_uint32_to_uint64 (1));
part = _cairo_uint128_sub (part, den);
}
q1 = _cairo_uint32_to_uint64 (0);
num = _cairo_uint128_sub (num, part);
num = _cairo_uint128_rsl (num, norm);
r0 = num.lo;
r1 = num.hi;
}
num = _cairo_uint128_sub (num, den);
quo = _cairo_uint128_add (quo, bit);
}
bit = _cairo_uint128_rsl (bit, 1);
den = _cairo_uint128_rsl (den, 1);
}
qr.quo.lo = q0;
qr.quo.hi = q1;
qr.rem.lo = r0;
qr.rem.hi = r1;
qr.quo = quo;
qr.rem = num;
return qr;
}

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: cairo-wideint.h,v 1.6 2005/06/04 07:03:27 vladimir%pobox.com Exp $
* $Id: cairo-wideint.h,v 1.11 2006/02/03 04:49:23 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
@ -44,8 +44,20 @@
# include <inttypes.h>
#elif HAVE_SYS_INT_TYPES_H
# 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;
# ifndef HAVE_UINT64_T
# define HAVE_UINT64_T 1
# endif
#else
# include "mozstdint.h"
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
#endif
/*
@ -85,7 +97,7 @@ cairo_int64_t I _cairo_int32_to_int64(int32_t i);
#define _cairo_int64_add(a,b) _cairo_uint64_add (a,b)
#define _cairo_int64_sub(a,b) _cairo_uint64_sub (a,b)
#define _cairo_int64_mul(a,b) _cairo_uint64_mul (a,b)
int I _cairo_int32x32_64_mul (int32_t a, int32_t b);
cairo_int64_t I _cairo_int32x32_64_mul (int32_t a, int32_t b);
int I _cairo_int64_lt (cairo_uint64_t a, cairo_uint64_t b);
#define _cairo_int64_eq(a,b) _cairo_uint64_eq (a,b)
#define _cairo_int64_lsl(a,b) _cairo_uint64_lsl (a,b)
@ -208,7 +220,7 @@ cairo_int128_t I _cairo_int64_to_int128 (cairo_int64_t i);
#define _cairo_int128_add(a,b) _cairo_uint128_add(a,b)
#define _cairo_int128_sub(a,b) _cairo_uint128_sub(a,b)
#define _cairo_int128_mul(a,b) _cairo_uint128_mul(a,b)
cairo_uint128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b);
cairo_int128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b);
#define _cairo_int128_lsl(a,b) _cairo_uint128_lsl(a,b)
#define _cairo_int128_rsl(a,b) _cairo_uint128_rsl(a,b)
#define _cairo_int128_rsa(a,b) _cairo_uint128_rsa(a,b)

Просмотреть файл

@ -46,6 +46,9 @@
#ifndef CLEARTYPE_QUALITY
#define CLEARTYPE_QUALITY 5
#endif
#ifndef TT_PRIM_CSPLINE
#define TT_PRIM_CSPLINE 3
#endif
const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend;
@ -104,6 +107,8 @@ static void
_compute_transform (cairo_win32_scaled_font_t *scaled_font,
cairo_matrix_t *sc)
{
cairo_status_t status;
if (NEARLY_ZERO (sc->yx) && NEARLY_ZERO (sc->xy)) {
scaled_font->preserve_axes = TRUE;
scaled_font->x_scale = sc->xx;
@ -154,39 +159,47 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
1.0 / scaled_font->logical_scale, 1.0 / scaled_font->logical_scale);
scaled_font->device_to_logical = scaled_font->logical_to_device;
if (!CAIRO_OK (cairo_matrix_invert (&scaled_font->device_to_logical)))
cairo_matrix_init_identity (&scaled_font->device_to_logical);
status = cairo_matrix_invert (&scaled_font->device_to_logical);
if (status)
cairo_matrix_init_identity (&scaled_font->device_to_logical);
}
static cairo_bool_t
_have_cleartype_quality (void)
{
OSVERSIONINFO version_info;
version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (!GetVersionEx (&version_info)) {
_cairo_win32_print_gdi_error ("_have_cleartype_quality");
return FALSE;
}
return (version_info.dwMajorVersion > 5 ||
(version_info.dwMajorVersion == 5 &&
version_info.dwMinorVersion >= 1)); /* XP or newer */
}
static BYTE
_get_system_quality (void)
{
BOOL font_smoothing;
UINT smoothing_type;
if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
_cairo_win32_print_gdi_error ("_get_system_quality");
return FALSE;
return DEFAULT_QUALITY;
}
if (font_smoothing) {
OSVERSIONINFO version_info;
version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (!GetVersionEx (&version_info)) {
_cairo_win32_print_gdi_error ("_get_system_quality");
return FALSE;
}
if (version_info.dwMajorVersion > 5 ||
(version_info.dwMajorVersion == 5 &&
version_info.dwMinorVersion >= 1)) { /* XP or newer */
UINT smoothing_type;
if (_have_cleartype_quality ()) {
if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,
0, &smoothing_type, 0)) {
_cairo_win32_print_gdi_error ("_get_system_quality");
return FALSE;
return DEFAULT_QUALITY;
}
if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)
@ -194,24 +207,54 @@ _get_system_quality (void)
}
return ANTIALIASED_QUALITY;
} else
} else {
return DEFAULT_QUALITY;
}
}
static cairo_scaled_font_t *
_win32_scaled_font_create (LOGFONTW *logfont,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm)
_win32_scaled_font_create (LOGFONTW *logfont,
cairo_font_face_t *font_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options)
{
cairo_win32_scaled_font_t *f;
cairo_matrix_t scale;
f = malloc (sizeof(cairo_win32_scaled_font_t));
if (f == NULL)
return NULL;
if (f == NULL)
return NULL;
f->logfont = *logfont;
f->quality = _get_system_quality ();
/* We don't have any control over the hinting style or subpixel
* order in the Win32 font API, so we ignore those parts of
* cairo_font_options_t. We use the 'antialias' field to set
* the 'quality'.
*
* XXX: The other option we could pay attention to, but don't
* here is the hint_metrics options.
*/
if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
f->quality = _get_system_quality ();
else {
switch (options->antialias) {
case CAIRO_ANTIALIAS_NONE:
f->quality = NONANTIALIASED_QUALITY;
break;
case CAIRO_ANTIALIAS_GRAY:
f->quality = ANTIALIASED_QUALITY;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
if (_have_cleartype_quality ())
f->quality = CLEARTYPE_QUALITY;
else
f->quality = ANTIALIASED_QUALITY;
break;
}
}
f->em_square = 0;
f->scaled_hfont = NULL;
f->unscaled_hfont = NULL;
@ -219,7 +262,9 @@ _win32_scaled_font_create (LOGFONTW *logfont,
cairo_matrix_multiply (&scale, font_matrix, ctm);
_compute_transform (f, &scale);
_cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_win32_scaled_font_backend);
_cairo_scaled_font_init (&f->base, font_face,
font_matrix, ctm, options,
&cairo_win32_scaled_font_backend);
return &f->base;
}
@ -367,7 +412,7 @@ _cairo_win32_scaled_font_select_unscaled_font (cairo_scaled_font_t *scaled_font,
return _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_select_unscaled_font");
status = _win32_scaled_font_set_identity_transform (hdc);
if (!CAIRO_OK (status)) {
if (status) {
SelectObject (hdc, old_hfont);
return status;
}
@ -385,12 +430,11 @@ _cairo_win32_scaled_font_done_unscaled_font (cairo_scaled_font_t *scaled_font)
/* implement the font backend interface */
static cairo_status_t
_cairo_win32_scaled_font_create (const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
cairo_scaled_font_t **scaled_font_out)
_cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_scaled_font_t **scaled_font_out)
{
LOGFONTW logfont;
cairo_scaled_font_t *scaled_font;
@ -398,8 +442,9 @@ _cairo_win32_scaled_font_create (const char *family,
int face_name_len;
cairo_status_t status;
status = _cairo_utf8_to_utf16 (family, -1, &face_name, &face_name_len);
if (!CAIRO_OK (status))
status = _cairo_utf8_to_utf16 (toy_face->family, -1,
&face_name, &face_name_len);
if (status)
return status;
if (face_name_len > LF_FACESIZE - 1) {
@ -415,7 +460,7 @@ _cairo_win32_scaled_font_create (const char *family,
logfont.lfEscapement = 0; /* filled in later */
logfont.lfOrientation = 0; /* filled in later */
switch (weight) {
switch (toy_face->weight) {
case CAIRO_FONT_WEIGHT_NORMAL:
default:
logfont.lfWeight = FW_NORMAL;
@ -425,7 +470,7 @@ _cairo_win32_scaled_font_create (const char *family,
break;
}
switch (slant) {
switch (toy_face->slant) {
case CAIRO_FONT_SLANT_NORMAL:
default:
logfont.lfItalic = FALSE;
@ -451,7 +496,8 @@ _cairo_win32_scaled_font_create (const char *family,
if (!logfont.lfFaceName)
return CAIRO_STATUS_NO_MEMORY;
scaled_font = _win32_scaled_font_create (&logfont, font_matrix, ctm);
scaled_font = _win32_scaled_font_create (&logfont, toy_face,
font_matrix, ctm, options);
if (!scaled_font)
return CAIRO_STATUS_NO_MEMORY;
@ -461,10 +507,13 @@ _cairo_win32_scaled_font_create (const char *family,
}
static void
_cairo_win32_scaled_font_destroy (void *abstract_font)
_cairo_win32_scaled_font_fini (void *abstract_font)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font;
if (scaled_font == NULL)
return;
if (scaled_font->scaled_hfont)
DeleteObject (scaled_font->scaled_hfont);
@ -496,7 +545,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
HDC hdc = NULL;
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16);
if (!CAIRO_OK (status))
if (status)
return status;
gcp_results.lStructSize = sizeof (GCP_RESULTS);
@ -518,7 +567,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
}
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (!CAIRO_OK (status))
if (status)
goto FAIL1;
while (TRUE) {
@ -610,7 +659,7 @@ _cairo_win32_scaled_font_font_extents (void *abstract_font,
* from the GDI in logical space, then convert back to font space
*/
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (!CAIRO_OK (status))
if (status)
return status;
GetTextMetrics (hdc, &metrics);
cairo_win32_scaled_font_done_font (&scaled_font->base);
@ -629,7 +678,7 @@ _cairo_win32_scaled_font_font_extents (void *abstract_font,
* avoid them.
*/
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
if (!CAIRO_OK (status))
if (status)
return status;
GetTextMetrics (hdc, &metrics);
_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
@ -672,7 +721,7 @@ _cairo_win32_scaled_font_glyph_extents (void *abstract_font,
* from the GDI in device space and convert to font space.
*/
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (!CAIRO_OK (status))
if (status)
return status;
GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX,
&metrics, 0, NULL, &matrix);
@ -745,7 +794,7 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
return CAIRO_STATUS_NO_MEMORY;
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (!CAIRO_OK (status))
if (status)
return status;
for (i = 0; i < num_glyphs; i++) {
@ -844,7 +893,7 @@ _add_glyph (cairo_glyph_state_t *state,
if (logical_y != state->last_y) {
cairo_status_t status = _flush_glyphs (state);
if (!CAIRO_OK (status))
if (status)
return status;
state->start_x = logical_x;
}
@ -890,7 +939,7 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
return _cairo_win32_print_gdi_error ("_draw_glyphs_on_surface:SaveDC");
status = cairo_win32_scaled_font_select_font (&scaled_font->base, surface->dc);
if (!CAIRO_OK (status))
if (status)
goto FAIL1;
SetTextColor (surface->dc, color);
@ -902,7 +951,7 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
for (i = 0; i < num_glyphs; i++) {
status = _add_glyph (&state, glyphs[i].index,
glyphs[i].x - x_offset, glyphs[i].y - y_offset);
if (!CAIRO_OK (status))
if (status)
goto FAIL2;
}
@ -910,7 +959,7 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
_finish_glyphs (&state);
cairo_win32_scaled_font_done_font (&scaled_font->base);
FAIL1:
RestoreDC (surface->dc, 1);
RestoreDC (surface->dc, -1);
return status;
}
@ -961,7 +1010,7 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,
image24->width, image24->height);
if (!image8)
if (image8->base.status)
return NULL;
for (i = 0; i < image24->height; i++) {
@ -1011,7 +1060,6 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
*/
COLORREF new_color;
/* XXX Use the unpremultiplied or premultiplied color? */
new_color = RGB (((int)solid_pattern->color.red_short) >> 8,
((int)solid_pattern->color.green_short) >> 8,
((int)solid_pattern->color.blue_short) >> 8);
@ -1034,7 +1082,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
RECT r;
tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
if (!tmp_surface)
if (tmp_surface->base.status)
return CAIRO_STATUS_NO_MEMORY;
r.left = 0;
@ -1093,25 +1141,148 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
}
}
static cairo_status_t
_cairo_win32_scaled_font_glyph_path (void *abstract_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_path_fixed_t *path)
static cairo_fixed_t
_cairo_fixed_from_FIXED (FIXED f)
{
return CAIRO_STATUS_SUCCESS;
return *((cairo_fixed_t *)&f);
}
static cairo_status_t
_cairo_win32_scaled_font_glyph_path (void *abstract_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_path_fixed_t *path)
{
static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, -1 } };
cairo_win32_scaled_font_t *scaled_font = abstract_font;
cairo_status_t status;
GLYPHMETRICS metrics;
HDC hdc;
int i;
hdc = _get_global_font_dc ();
if (!hdc)
return CAIRO_STATUS_NO_MEMORY;
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
if (status)
return status;
for (i = 0; i < num_glyphs; i++)
{
DWORD bytesGlyph;
unsigned char *buffer, *ptr;
cairo_fixed_t x = _cairo_fixed_from_double (glyphs[i].x);
cairo_fixed_t y = _cairo_fixed_from_double (glyphs[i].y);
bytesGlyph = GetGlyphOutlineW (hdc, glyphs[i].index,
GGO_NATIVE | GGO_GLYPH_INDEX,
&metrics, 0, NULL, &matrix);
if (bytesGlyph == GDI_ERROR) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
goto FAIL;
}
ptr = buffer = malloc (bytesGlyph);
if (!buffer) {
status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
}
if (GetGlyphOutlineW (hdc, glyphs[i].index,
GGO_NATIVE | GGO_GLYPH_INDEX,
&metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
free (buffer);
goto FAIL;
}
while (ptr < buffer + bytesGlyph) {
TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr;
unsigned char *endPoly = ptr + header->cb;
ptr += sizeof (TTPOLYGONHEADER);
_cairo_path_fixed_move_to (path,
_cairo_fixed_from_FIXED (header->pfxStart.x) + x,
_cairo_fixed_from_FIXED (header->pfxStart.y) + y);
while (ptr < endPoly) {
TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
POINTFX *points = curve->apfx;
int i;
switch (curve->wType) {
case TT_PRIM_LINE:
for (i = 0; i < curve->cpfx; i++) {
_cairo_path_fixed_line_to (path,
_cairo_fixed_from_FIXED (points[i].x) + x,
_cairo_fixed_from_FIXED (points[i].y) + y);
}
break;
case TT_PRIM_QSPLINE:
for (i = 0; i < curve->cpfx - 1; i++) {
cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
_cairo_path_fixed_get_current_point (path, &p1x, &p1y);
cx = _cairo_fixed_from_FIXED (points[i].x) + x;
cy = _cairo_fixed_from_FIXED (points[i].y) + y;
if (i + 1 == curve->cpfx - 1) {
p2x = _cairo_fixed_from_FIXED (points[i + 1].x) + x;
p2y = _cairo_fixed_from_FIXED (points[i + 1].y) + y;
} else {
/* records with more than one curve use interpolation for
control points, per http://support.microsoft.com/kb/q87115/ */
p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x) + x) / 2;
p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y) + y) / 2;
}
c1x = 2 * cx / 3 + p1x / 3;
c1y = 2 * cy / 3 + p1y / 3;
c2x = 2 * cx / 3 + p2x / 3;
c2y = 2 * cy / 3 + p2y / 3;
_cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
}
break;
case TT_PRIM_CSPLINE:
for (i = 0; i < curve->cpfx - 2; i += 2) {
_cairo_path_fixed_curve_to (path,
_cairo_fixed_from_FIXED (points[i].x) + x,
_cairo_fixed_from_FIXED (points[i].y) + y,
_cairo_fixed_from_FIXED (points[i + 1].x) + x,
_cairo_fixed_from_FIXED (points[i + 1].y) + y,
_cairo_fixed_from_FIXED (points[i + 2].x) + x,
_cairo_fixed_from_FIXED (points[i + 2].y) + y);
}
break;
}
ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);
}
_cairo_path_fixed_close_path (path);
}
free(buffer);
}
FAIL:
cairo_win32_scaled_font_done_font (&scaled_font->base);
return status;
}
const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
_cairo_win32_scaled_font_create,
_cairo_win32_scaled_font_destroy,
_cairo_win32_scaled_font_create_toy,
_cairo_win32_scaled_font_fini,
_cairo_win32_scaled_font_font_extents,
_cairo_win32_scaled_font_text_to_glyphs,
_cairo_win32_scaled_font_glyph_extents,
_cairo_win32_scaled_font_glyph_bbox,
_cairo_win32_scaled_font_show_glyphs,
_cairo_win32_scaled_font_glyph_path,
_cairo_win32_scaled_font_get_glyph_cache_key,
_cairo_win32_scaled_font_get_glyph_cache_key
};
/* cairo_win32_font_face_t */
@ -1131,15 +1302,17 @@ _cairo_win32_font_face_destroy (void *abstract_face)
}
static cairo_status_t
_cairo_win32_font_face_create_font (void *abstract_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
cairo_scaled_font_t **font)
_cairo_win32_font_face_scaled_font_create (void *abstract_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_scaled_font_t **font)
{
cairo_win32_font_face_t *font_face = abstract_face;
*font = _win32_scaled_font_create (&font_face->logfont,
font_matrix, ctm);
font_face,
font_matrix, ctm, options);
if (*font)
return CAIRO_STATUS_SUCCESS;
else
@ -1148,11 +1321,11 @@ _cairo_win32_font_face_create_font (void *abstract_face,
static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
_cairo_win32_font_face_destroy,
_cairo_win32_font_face_create_font,
_cairo_win32_font_face_scaled_font_create
};
/**
* cairo_win32_scaled_font_create_for_logfontw:
* cairo_win32_font_face_create_for_logfontw:
* @logfont: A #LOGFONTW structure specifying the font to use.
* The lfHeight, lfWidth, lfOrientation and lfEscapement
* fields of this structure are ignored.
@ -1172,8 +1345,10 @@ cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont)
cairo_win32_font_face_t *font_face;
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face)
return NULL;
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
font_face->logfont = *logfont;
@ -1215,6 +1390,11 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,
HFONT old_hfont = NULL;
int old_mode;
if (scaled_font->status) {
_cairo_scaled_font_set_error (scaled_font, scaled_font->status);
return scaled_font->status;
}
hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
if (!hfont)
return CAIRO_STATUS_NO_MEMORY;
@ -1231,7 +1411,7 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,
}
status = _win32_scaled_font_set_world_transform ((cairo_win32_scaled_font_t *)scaled_font, hdc);
if (!CAIRO_OK (status)) {
if (status) {
SetGraphicsMode (hdc, old_mode);
SelectObject (hdc, old_hfont);
return status;

Просмотреть файл

@ -1,6 +1,6 @@
/* Cairo - a vector graphics library with display and print output
*
* Copyright <EFBFBD>Â<EFBFBD>© 2005 Red Hat, Inc.
* 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
@ -240,27 +240,32 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
static cairo_surface_t *
_cairo_win32_surface_create_for_dc (HDC original_dc,
cairo_format_t format,
int drawable,
int width,
int height)
{
cairo_status_t status;
cairo_win32_surface_t *surface;
char *bits;
int rowstride;
surface = malloc (sizeof (cairo_win32_surface_t));
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
if (_create_dc_and_bitmap (surface, original_dc, format,
width, height,
&bits, &rowstride) != CAIRO_STATUS_SUCCESS)
status = _create_dc_and_bitmap (surface, original_dc, format,
width, height,
&bits, &rowstride);
if (status)
goto FAIL;
surface->image = cairo_image_surface_create_for_data (bits, format,
width, height, rowstride);
if (!surface->image)
if (surface->image->status) {
status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
}
surface->format = format;
@ -284,22 +289,26 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
}
if (surface)
free (surface);
return NULL;
if (status == CAIRO_STATUS_NO_MEMORY) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
} else {
_cairo_error (status);
return &_cairo_surface_nil;
}
}
static cairo_surface_t *
_cairo_win32_surface_create_similar (void *abstract_src,
cairo_format_t format,
int drawable,
cairo_content_t content,
int width,
int height)
{
cairo_win32_surface_t *src = abstract_src;
cairo_format_t format = _cairo_format_from_content (content);
return _cairo_win32_surface_create_for_dc (src->dc, format, drawable,
width, height);
return _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
}
/**
@ -320,8 +329,7 @@ _cairo_win32_surface_create_dib (cairo_format_t format,
int width,
int height)
{
return _cairo_win32_surface_create_for_dc (NULL, format, TRUE,
width, height);
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
}
static cairo_status_t
@ -332,8 +340,9 @@ _cairo_win32_surface_finish (void *abstract_surface)
if (surface->image)
cairo_surface_destroy (surface->image);
if (surface->saved_clip)
if (surface->saved_clip) {
DeleteObject (surface->saved_clip);
}
/* If we created the Bitmap and DC, destroy them */
if (surface->bitmap) {
@ -355,13 +364,14 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
{
cairo_win32_surface_t *local;
cairo_status_t status;
cairo_content_t content = _cairo_content_from_format (surface->format);
local =
(cairo_win32_surface_t *) _cairo_win32_surface_create_similar (surface,
surface->format,
0,
width, height);
if (!local)
content,
width,
height);
if (local->base.status)
return CAIRO_STATUS_NO_MEMORY;
if (!BitBlt (local->dc,
@ -404,12 +414,13 @@ _cairo_win32_surface_acquire_source_image (void *abstract_sur
status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
surface->clip_rect.width,
surface->clip_rect.height, &local);
if (CAIRO_OK (status)) {
*image_out = (cairo_image_surface_t *)local->image;
*image_extra = local;
}
if (status)
return status;
return status;
*image_out = (cairo_image_surface_t *)local->image;
*image_extra = local;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -475,17 +486,18 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
status = _cairo_win32_surface_get_subimage (abstract_surface,
x1, y1, x2 - x1, y2 - y1,
&local);
if (CAIRO_OK (status)) {
*image_out = (cairo_image_surface_t *)local->image;
*image_extra = local;
image_rect->x = x1;
image_rect->y = y1;
image_rect->width = x2 - x1;
image_rect->height = y2 - y1;
}
if (status)
return status;
return status;
*image_out = (cairo_image_surface_t *)local->image;
*image_extra = local;
image_rect->x = x1;
image_rect->y = y1;
image_rect->width = x2 - x1;
image_rect->height = y2 - y1;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -628,7 +640,6 @@ _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 &&
!src->base.repeat &&
operator == CAIRO_OPERATOR_OVER) {
BLENDFUNCTION blend_function;
@ -729,6 +740,9 @@ categorize_solid_dest_operator (cairo_operator_t operator,
return DO_UNSUPPORTED;
break;
}
ASSERT_NOT_REACHED;
return DO_UNSUPPORTED;
}
static cairo_int_status_t
@ -758,7 +772,7 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
new_color = RGB (0, 0, 0);
break;
case DO_SOURCE:
new_color = RGB (color->red_short >> 8, color->blue_short >> 8, color->green_short >> 8);
new_color = RGB (color->red_short >> 8, color->green_short >> 8, color->blue_short >> 8);
break;
case DO_NOTHING:
return CAIRO_STATUS_SUCCESS;
@ -805,8 +819,12 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
/* If we are in-memory, then we set the clip on the image surface
* as well as on the underlying GDI surface.
*/
if (surface->image)
_cairo_surface_set_clip_region (surface->image, region);
if (surface->image) {
unsigned int serial;
serial = _cairo_surface_allocate_clip_serial (surface->image);
_cairo_surface_set_clip_region (surface->image, region, serial);
}
/* The semantics we want is that any clip set by cairo combines
* is intersected with the clip on device context that the
@ -829,7 +847,6 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
surface->set_clip = 0;
}
return CAIRO_STATUS_SUCCESS;
} else {
@ -930,6 +947,12 @@ _cairo_win32_surface_get_extents (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_win32_surface_flush (void *abstract_surface)
{
return _cairo_surface_reset_clip (abstract_surface);
}
cairo_surface_t *
cairo_win32_surface_create (HDC hdc)
{
@ -940,12 +963,16 @@ cairo_win32_surface_create (HDC hdc)
*/
if (GetClipBox (hdc, &rect) == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
return NULL;
/* XXX: Can we make a more reasonable guess at the error cause here? */
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
surface = malloc (sizeof (cairo_win32_surface_t));
if (!surface)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
}
surface->image = NULL;
surface->format = CAIRO_FORMAT_RGB24;
@ -995,6 +1022,11 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
NULL, /* copy_page */
NULL, /* show_page */
_cairo_win32_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_win32_surface_get_extents,
NULL /* show_glyphs */
NULL, /* show_glyphs */
NULL, /* fill_path */
NULL, /* get_font_options */
_cairo_win32_surface_flush,
NULL /* mark_dirty_rectangle */
};

Просмотреть файл

@ -38,7 +38,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_WIN32_SURFACE
#if CAIRO_HAS_WIN32_SURFACE
#include <windows.h>

Просмотреть файл

@ -228,8 +228,7 @@ _CAIRO_FORMAT_DEPTH (cairo_format_t format)
static cairo_surface_t *
_cairo_xcb_surface_create_similar (void *abstract_src,
cairo_format_t format,
int drawable,
cairo_content_t content,
int width,
int height)
{
@ -237,6 +236,7 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
XCBConnection *dpy = src->dpy;
XCBDRAWABLE d;
cairo_xcb_surface_t *surface;
cairo_format_t format = _cairo_format_from_content (content);
XCBRenderPICTFORMINFO xrender_format = _format_from_cairo (dpy, format);
/* As a good first approximation, if the display doesn't have COMPOSITE,
@ -256,6 +256,10 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
cairo_xcb_surface_create_with_xrender_format (dpy, d,
&xrender_format,
width, height);
if (surface->base.status) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface->owns_pixmap = TRUE;
@ -371,7 +375,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
rect.x = interest_rect->x;
rect.y = interest_rect->y;
rect.width = interest_rect->width;
rect.height = interest_rect->width;
rect.height = interest_rect->height;
if (rect.x > x1)
x1 = rect.x;
@ -477,10 +481,10 @@ _get_image_surface (cairo_xcb_surface_t *surface,
masks.blue_mask = surface->visual->blue_mask;
} else if (surface->has_format) {
masks.bpp = bpp;
masks.red_mask = surface->format.direct.red_mask << surface->format.direct.red_shift;
masks.green_mask = surface->format.direct.green_mask << surface->format.direct.green_shift;
masks.blue_mask = surface->format.direct.blue_mask << surface->format.direct.blue_shift;
masks.alpha_mask = surface->format.direct.alpha_mask << surface->format.direct.alpha_shift;
masks.red_mask = (unsigned long)surface->format.direct.red_mask << surface->format.direct.red_shift;
masks.green_mask = (unsigned long)surface->format.direct.green_mask << surface->format.direct.green_shift;
masks.blue_mask = (unsigned long)surface->format.direct.blue_mask << surface->format.direct.blue_shift;
masks.alpha_mask = (unsigned long)surface->format.direct.alpha_mask << surface->format.direct.alpha_shift;
} else {
masks.bpp = bpp;
masks.red_mask = 0;
@ -503,6 +507,8 @@ _get_image_surface (cairo_xcb_surface_t *surface,
x2 - x1,
y2 - y1,
bytes_per_line);
if (image->base.status)
goto FAIL;
} else {
/*
* XXX This can't work. We must convert the data to one of the
@ -510,22 +516,25 @@ _get_image_surface (cairo_xcb_surface_t *surface,
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
image = _cairo_image_surface_create_with_masks (data,
&masks,
x2 - x1,
y2 - y1,
bytes_per_line);
image = (cairo_image_surface_t *)
_cairo_image_surface_create_with_masks (data,
&masks,
x2 - x1,
y2 - y1,
bytes_per_line);
if (image->base.status)
goto FAIL;
}
/* Let the surface take ownership of the data */
_cairo_image_surface_assume_ownership_of_data (image);
_cairo_image_surface_set_repeat (image, surface->base.repeat);
_cairo_image_surface_set_matrix (image, &(surface->base.matrix));
*image_out = image;
return CAIRO_STATUS_SUCCESS;
FAIL:
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
static void
@ -569,10 +578,13 @@ _cairo_xcb_surface_acquire_source_image (void *abstract_surfa
cairo_status_t status;
status = _get_image_surface (surface, NULL, &image, NULL);
if (status == CAIRO_STATUS_SUCCESS)
*image_out = image;
if (status)
return status;
return status;
*image_out = image;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -595,10 +607,13 @@ _cairo_xcb_surface_acquire_dest_image (void *abstract_surface
cairo_status_t status;
status = _get_image_surface (surface, interest_rect, &image, image_rect_out);
if (status == CAIRO_STATUS_SUCCESS)
*image_out = image;
if (status)
return status;
return status;
*image_out = image;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -628,18 +643,21 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
cairo_xcb_surface_t *xcb_src = (cairo_xcb_surface_t *)src;
if (xcb_src->dpy == surface->dpy) {
*clone_out = src;
cairo_surface_reference (src);
*clone_out = 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;
cairo_content_t content = _cairo_content_from_format (image_src->format);
if (surface->base.status)
return surface->base.status;
clone = (cairo_xcb_surface_t *)
_cairo_xcb_surface_create_similar (surface, image_src->format, 0,
_cairo_xcb_surface_create_similar (surface, content,
image_src->width, image_src->height);
if (clone == NULL)
if (clone->base.status)
return CAIRO_STATUS_NO_MEMORY;
_draw_image_surface (clone, image_src, 0, 0);
@ -850,12 +868,12 @@ _cairo_xcb_surface_composite (cairo_operator_t operator,
return status;
status = _cairo_xcb_surface_set_attributes (src, &src_attr);
if (CAIRO_OK (status))
if (status == CAIRO_STATUS_SUCCESS)
{
if (mask)
{
status = _cairo_xcb_surface_set_attributes (mask, &mask_attr);
if (CAIRO_OK (status))
if (status == CAIRO_STATUS_SUCCESS)
XCBRenderComposite (dst->dpy,
_render_operator (operator),
src->picture,
@ -886,9 +904,9 @@ _cairo_xcb_surface_composite (cairo_operator_t operator,
}
if (mask)
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
_cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr);
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
_cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
return status;
}
@ -924,6 +942,7 @@ static cairo_int_status_t
_cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator,
cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
int src_y,
int dst_x,
@ -962,11 +981,19 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator,
render_src_x = src_x + render_reference_x - dst_x;
render_src_y = src_y + render_reference_y - dst_y;
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1);
break;
default:
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8);
break;
}
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
/* XXX: _format_from_cairo is slow. should cache something. */
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8),
status = _cairo_xcb_surface_set_attributes (src, &attributes);
if (CAIRO_OK (status))
if (status == CAIRO_STATUS_SUCCESS)
XCBRenderTrapezoids (dst->dpy,
_render_operator (operator),
src->picture, dst->picture,
@ -975,19 +1002,11 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator,
render_src_y + attributes.y_offset,
num_traps, (XCBRenderTRAP *) traps);
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
return status;
}
static cairo_int_status_t
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
pixman_region16_t *region)
{
/* XXX: FIXME */
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_xcb_surface_get_extents (void *abstract_surface,
cairo_rectangle_t *rectangle)
@ -1016,7 +1035,8 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
_cairo_xcb_surface_composite_trapezoids,
NULL, /* copy_page */
NULL, /* show_page */
_cairo_xcb_surface_set_clip_region,
NULL, /* _cairo_xcb_surface_set_clip_region */
NULL, /* intersect_clip_path */
_cairo_xcb_surface_get_extents,
NULL /* show_glyphs */
};
@ -1067,8 +1087,10 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
cairo_xcb_surface_t *surface;
surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL)
return NULL;
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_surface_init (&surface->base, &cairo_xcb_surface_backend);

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_XCB_SURFACE
#if CAIRO_HAS_XCB_SURFACE
#include <X11/XCB/xcb.h>
#include <X11/XCB/render.h>

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_XCB_SURFACE
#if CAIRO_HAS_XCB_SURFACE
#include <X11/XCB/xcb.h>
@ -47,7 +47,7 @@ CAIRO_BEGIN_DECLS
cairo_surface_t *
cairo_xcb_surface_create (XCBConnection *c,
XCBDRAWABLE pixmap,
XCBDRAWABLE drawable,
XCBVISUALTYPE *visual,
int width,
int height);

Просмотреть файл

@ -0,0 +1,54 @@
/* 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.
*/
#ifndef CAIRO_XLIB_PRIVATE_H
#define CAIRO_XLIB_PRIVATE_H
#include "cairoint.h"
#include "cairo-xlib.h"
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
struct _cairo_xlib_screen_info {
cairo_xlib_screen_info_t *next;
Display *display;
Screen *screen;
cairo_bool_t has_render;
cairo_font_options_t font_options;
};
cairo_private cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_get (Display *display, Screen *screen);
#endif /* CAIRO_XLIB_PRIVATE_H */

Просмотреть файл

@ -0,0 +1,381 @@
/* 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.
*
* Partially on code from xftdpy.c
*
* Copyright © 2000 Keith Packard
*
* 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 and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD 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, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "cairo-xlib-private.h"
#include <fontconfig/fontconfig.h>
#include <X11/Xlibint.h> /* For XESetCloseDisplay */
#include <X11/extensions/Xrender.h>
static int
parse_boolean (const char *v)
{
char c0, c1;
c0 = *v;
if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1')
return 1;
if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0')
return 0;
if (c0 == 'o')
{
c1 = v[1];
if (c1 == 'n' || c1 == 'N')
return 1;
if (c1 == 'f' || c1 == 'F')
return 0;
}
return -1;
}
static cairo_bool_t
get_boolean_default (Display *dpy,
const char *option,
cairo_bool_t *value)
{
char *v;
int i;
v = XGetDefault (dpy, "Xft", option);
if (v) {
i = parse_boolean (v);
if (i >= 0) {
*value = i;
return TRUE;
}
}
return FALSE;
}
static cairo_bool_t
get_integer_default (Display *dpy,
const char *option,
int *value)
{
int i;
char *v, *e;
v = XGetDefault (dpy, "Xft", option);
if (v) {
if (FcNameConstant ((FcChar8 *) v, value))
return TRUE;
i = strtol (v, &e, 0);
if (e != v)
return TRUE;
}
return FALSE;
}
/* Old versions of fontconfig didn't have these options */
#ifndef FC_HINT_NONE
#define FC_HINT_NONE 0
#define FC_HINT_SLIGHT 1
#define FC_HINT_MEDIUM 2
#define FC_HINT_FULL 3
#endif
static void
_cairo_xlib_init_screen_font_options (cairo_xlib_screen_info_t *info)
{
cairo_bool_t xft_hinting;
cairo_bool_t xft_antialias;
int xft_hintstyle;
int xft_rgba;
cairo_antialias_t antialias;
cairo_subpixel_order_t subpixel_order;
cairo_hint_style_t hint_style;
if (!get_boolean_default (info->display, "antialias", &xft_antialias))
xft_antialias = TRUE;
if (!get_boolean_default (info->display, "hinting", &xft_hinting))
xft_hinting = TRUE;
if (!get_integer_default (info->display, "hintstyle", &xft_hintstyle))
xft_hintstyle = FC_HINT_FULL;
if (!get_integer_default (info->display, "rgba", &xft_rgba))
{
xft_rgba = FC_RGBA_UNKNOWN;
#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
if (info->has_render)
{
int render_order = XRenderQuerySubpixelOrder (info->display,
XScreenNumberOfScreen (info->screen));
switch (render_order)
{
default:
case SubPixelUnknown:
xft_rgba = FC_RGBA_UNKNOWN;
break;
case SubPixelHorizontalRGB:
xft_rgba = FC_RGBA_RGB;
break;
case SubPixelHorizontalBGR:
xft_rgba = FC_RGBA_BGR;
break;
case SubPixelVerticalRGB:
xft_rgba = FC_RGBA_VRGB;
break;
case SubPixelVerticalBGR:
xft_rgba = FC_RGBA_VBGR;
break;
case SubPixelNone:
xft_rgba = FC_RGBA_NONE;
break;
}
}
#endif
}
if (xft_hinting) {
switch (xft_hintstyle) {
case FC_HINT_NONE:
hint_style = CAIRO_HINT_STYLE_NONE;
break;
case FC_HINT_SLIGHT:
hint_style = CAIRO_HINT_STYLE_SLIGHT;
break;
case FC_HINT_MEDIUM:
hint_style = CAIRO_HINT_STYLE_MEDIUM;
break;
case FC_HINT_FULL:
hint_style = CAIRO_HINT_STYLE_FULL;
break;
default:
hint_style = CAIRO_HINT_STYLE_DEFAULT;
}
} else {
hint_style = CAIRO_HINT_STYLE_NONE;
}
switch (xft_rgba) {
case FC_RGBA_RGB:
subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
break;
case FC_RGBA_BGR:
subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
break;
case FC_RGBA_VRGB:
subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
break;
case FC_RGBA_VBGR:
subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
break;
case FC_RGBA_UNKNOWN:
case FC_RGBA_NONE:
default:
subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
}
if (xft_antialias) {
if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT)
antialias = CAIRO_ANTIALIAS_GRAY;
else
antialias = CAIRO_ANTIALIAS_SUBPIXEL;
} else {
antialias = CAIRO_ANTIALIAS_NONE;
}
_cairo_font_options_init_default (&info->font_options);
cairo_font_options_set_hint_style (&info->font_options, hint_style);
cairo_font_options_set_antialias (&info->font_options, antialias);
cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order);
}
CAIRO_MUTEX_DECLARE(_xlib_screen_mutex);
static cairo_xlib_screen_info_t *_cairo_xlib_screen_list = NULL;
static int
_cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
{
cairo_xlib_screen_info_t *info, *prev;
/*
* Unhook from the global list
*/
CAIRO_MUTEX_LOCK (_xlib_screen_mutex);
prev = NULL;
for (info = _cairo_xlib_screen_list; info; info = info->next) {
if (info->display == dpy) {
if (prev)
prev->next = info->next;
else
_cairo_xlib_screen_list = info->next;
free (info);
break;
}
prev = info;
}
CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex);
/* Return value in accordance with requirements of
* XESetCloseDisplay */
return 0;
}
static void
_cairo_xlib_screen_info_reset (void)
{
cairo_xlib_screen_info_t *info, *next;
/*
* Delete everything in the list.
*/
CAIRO_MUTEX_LOCK (_xlib_screen_mutex);
for (info = _cairo_xlib_screen_list; info; info = next) {
next = info->next;
free (info);
}
_cairo_xlib_screen_list = NULL;
CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex);
}
cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
{
cairo_xlib_screen_info_t *info;
cairo_xlib_screen_info_t **prev;
int event_base, error_base;
XExtCodes *codes;
cairo_bool_t seen_display = FALSE;
/* There is an apparent deadlock between this mutex and the
* mutex for the display, but it's actually safe. For the
* app to call XCloseDisplay() while any other thread is
* inside this function would be an error in the logic
* app, and the CloseDisplay hook is the only other place we
* acquire this mutex.
*/
CAIRO_MUTEX_LOCK (_xlib_screen_mutex);
for (prev = &_cairo_xlib_screen_list; (info = *prev); prev = &(*prev)->next)
{
if (info->display == dpy) {
seen_display = TRUE;
if (info->screen == screen)
{
/*
* MRU the list
*/
if (prev != &_cairo_xlib_screen_list)
{
*prev = info->next;
info->next = _cairo_xlib_screen_list;
_cairo_xlib_screen_list = info;
}
break;
}
}
}
if (info)
goto out;
info = malloc (sizeof (cairo_xlib_screen_info_t));
if (!info)
goto out;
if (!seen_display) {
codes = XAddExtension (dpy);
if (!codes) {
free (info);
info = NULL;
goto out;
}
XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
}
info->display = dpy;
info->screen = screen;
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
_cairo_xlib_init_screen_font_options (info);
info->next = _cairo_xlib_screen_list;
_cairo_xlib_screen_list = info;
out:
CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex);
return info;
}
void
_cairo_xlib_screen_reset_static_data (void)
{
_cairo_xlib_screen_info_reset ();
#if HAVE_XRMFINALIZE
XrmFinalize ();
#endif
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_XLIB_SURFACE
#if CAIRO_HAS_XLIB_SURFACE
#include <cairo-xlib.h>

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_XLIB_SURFACE
#if CAIRO_HAS_XLIB_SURFACE
#include <X11/extensions/Xrender.h>
@ -48,6 +48,7 @@ CAIRO_BEGIN_DECLS
cairo_surface_t *
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
Drawable drawable,
Screen *screen,
XRenderPictFormat *format,
int width,
int height);

Просмотреть файл

@ -39,7 +39,7 @@
#include <cairo.h>
#ifdef CAIRO_HAS_XLIB_SURFACE
#if CAIRO_HAS_XLIB_SURFACE
#include <X11/Xlib.h>
@ -55,6 +55,7 @@ cairo_xlib_surface_create (Display *dpy,
cairo_surface_t *
cairo_xlib_surface_create_for_bitmap (Display *dpy,
Pixmap bitmap,
Screen *screen,
int width,
int height);
@ -63,6 +64,12 @@ cairo_xlib_surface_set_size (cairo_surface_t *surface,
int width,
int height);
void
cairo_xlib_surface_set_drawable (cairo_surface_t *surface,
Drawable drawable,
int width,
int height);
CAIRO_END_DECLS
#else /* CAIRO_HAS_XLIB_SURFACE */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -38,18 +38,26 @@
#ifndef CAIRO_H
#define CAIRO_H
#ifdef __cplusplus
# define CAIRO_BEGIN_DECLS extern "C" {
# define CAIRO_END_DECLS }
#else
# define CAIRO_BEGIN_DECLS
# define CAIRO_END_DECLS
#endif
#include <cairo-features.h>
CAIRO_BEGIN_DECLS
#define CAIRO_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \
+ ((minor) * 100) \
+ ((micro) * 1))
#define CAIRO_VERSION CAIRO_VERSION_ENCODE( \
CAIRO_VERSION_MAJOR, \
CAIRO_VERSION_MINOR, \
CAIRO_VERSION_MICRO)
int
cairo_version (void);
const char*
cairo_version_string (void);
/**
* cairo_bool_t:
*
@ -90,9 +98,20 @@ typedef struct _cairo_surface cairo_surface_t;
/**
* cairo_matrix_t:
* @xx: xx component of the affine transformation
* @yx: yx component of the affine transformation
* @xy: xy component of the affine transformation
* @yy: yy component of the affine transformation
* @x0: X translation component of the affine transformation
* @y0: Y translation component of the affine transformation
*
* A #cairo_matrix_t holds an affine transformation, such as a scale,
* rotation, or shear, or a combination of those.
* rotation, or shear, or a combination of those. The transformation is given
* by:
* <programlisting>
* x_new = xx * x + xy * y + x0;
* y_new = yx * x + yy * y + y0;
* </programlisting>
**/
typedef struct _cairo_matrix {
double xx; double yx;
@ -103,7 +122,8 @@ typedef struct _cairo_matrix {
typedef struct _cairo_pattern cairo_pattern_t;
/**
* cairo_destroy_func_t
* cairo_destroy_func_t:
* @data: The data element being destroyed.
*
* #cairo_destroy_func_t the type of function which is called when a
* data element is destroyed. It is passed the pointer to the data
@ -112,7 +132,8 @@ typedef struct _cairo_pattern cairo_pattern_t;
typedef void (*cairo_destroy_func_t) (void *data);
/**
* cairo_user_data_key_t
* cairo_user_data_key_t:
* @unused: not used; ignore.
*
* #cairo_user_data_key_t is used for attaching user data to cairo
* data structures. The actual contents of the struct is never used,
@ -127,37 +148,38 @@ typedef struct _cairo_user_data_key {
/**
* cairo_status_t
* @CAIRO_STATUS_SUCCESS: no error has occurred
* @CAIRO_STATUS_NO_MEMORY:
* @CAIRO_STATUS_INVALID_RESTORE:
* @CAIRO_STATUS_INVALID_POP_GROUP:
* @CAIRO_STATUS_INVALID_MATRIX:
* @CAIRO_STATUS_NO_TARGET_SURFACE:
* @CAIRO_STATUS_NULL_POINTER:
* @CAIRO_STATUS_INVALID_STRING:
* @CAIRO_STATUS_INVALID_PATH_DATA:
* @CAIRO_STATUS_READ_ERROR:
* @CAIRO_STATUS_WRITE_ERROR:
* @CAIRO_STATUS_SURFACE_FINISHED:
* @CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
* @CAIRO_STATUS_BAD_NESTING: the same surface was used as the
* target surface for two different cairo contexts at once,
* and more drawing was done on the first context before the
* surface was unset as the target for the second context.
* See the documentation for cairo_create().
* @CAIRO_STATUS_NO_MEMORY: out of memory
* @CAIRO_STATUS_INVALID_RESTORE: cairo_restore without matching cairo_save
* @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop
* @CAIRO_STATUS_NO_CURRENT_POINT: no current point defined
* @CAIRO_STATUS_INVALID_MATRIX: invalid matrix (not invertible)
* @CAIRO_STATUS_INVALID_STATUS: invalid value for an input cairo_status_t
* @CAIRO_STATUS_NULL_POINTER: NULL pointer
* @CAIRO_STATUS_INVALID_STRING: input string not valid UTF-8
* @CAIRO_STATUS_INVALID_PATH_DATA: input path data not valid
* @CAIRO_STATUS_READ_ERROR: error while reading from input stream
* @CAIRO_STATUS_WRITE_ERROR: error while writing to output stream
* @CAIRO_STATUS_SURFACE_FINISHED: target surface has been finished
* @CAIRO_STATUS_SURFACE_TYPE_MISMATCH: the surface type is not appropriate for the operation
* @CAIRO_STATUS_PATTERN_TYPE_MISMATCH: the pattern type is not appropriate for the operation
* @CAIRO_STATUS_INVALID_CONTENT: invalid value for an input cairo_content_t
* @CAIRO_STATUS_INVALID_FORMAT: invalid value for an input cairo_format_t
* @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual*
* @CAIRO_STATUS_FILE_NOT_FOUND: file not found
*
* #cairo_status_t is used to indicate errors that can occur when
* using Cairo. In some cases it is returned directly by functions.
* but when using #cairo_t, the last error, if any, is stored in
* the context and can be retrieved with cairo_status().
**/
typedef enum cairo_status {
typedef enum _cairo_status {
CAIRO_STATUS_SUCCESS = 0,
CAIRO_STATUS_NO_MEMORY,
CAIRO_STATUS_INVALID_RESTORE,
CAIRO_STATUS_INVALID_POP_GROUP,
CAIRO_STATUS_NO_CURRENT_POINT,
CAIRO_STATUS_INVALID_MATRIX,
CAIRO_STATUS_NO_TARGET_SURFACE,
CAIRO_STATUS_INVALID_STATUS,
CAIRO_STATUS_NULL_POINTER,
CAIRO_STATUS_INVALID_STRING,
CAIRO_STATUS_INVALID_PATH_DATA,
@ -165,11 +187,18 @@ typedef enum cairo_status {
CAIRO_STATUS_WRITE_ERROR,
CAIRO_STATUS_SURFACE_FINISHED,
CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
CAIRO_STATUS_BAD_NESTING
CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
CAIRO_STATUS_INVALID_CONTENT,
CAIRO_STATUS_INVALID_FORMAT,
CAIRO_STATUS_INVALID_VISUAL,
CAIRO_STATUS_FILE_NOT_FOUND
} cairo_status_t;
/**
* cairo_write_func_t
* cairo_write_func_t:
* @closure: the output closure
* @data: the buffer containing the data to write
* @length: the amount of data to write
*
* #cairo_write_func_t is the type of function which is called when a
* backend needs to write data to an output stream. It is passed the
@ -178,21 +207,28 @@ typedef enum cairo_status {
* data in bytes. The write function should return
* CAIRO_STATUS_SUCCESS if all the data was successfully written,
* CAIRO_STATUS_WRITE_ERROR otherwise.
*
* Returns: the status code of the write operation
*/
typedef cairo_status_t (*cairo_write_func_t) (void *closure,
const unsigned char *data,
unsigned int length);
/**
* cairo_read_func_t
* cairo_read_func_t:
* @closure: the input closure
* @data: the buffer into which to read the data
* @length: the amount of data to read
*
* #cairo_read_func_t is the type of function which is called when a
* backend needs to read data from an intput stream. It is passed the
* closure which was specified by the user at the time the read
* function was registered, the buffer to read the data into and the
* length of the data in bytes. The read function should return
* CAIRO_STATUS_SUCCESS if all the data was successfully written,
* CAIRO_STATUS_SUCCESS if all the data was successfully read,
* CAIRO_STATUS_READ_ERROR otherwise.
*
* Returns: the status code of the read operation
*/
typedef cairo_status_t (*cairo_read_func_t) (void *closure,
unsigned char *data,
@ -202,7 +238,7 @@ typedef cairo_status_t (*cairo_read_func_t) (void *closure,
cairo_t *
cairo_create (cairo_surface_t *target);
void
cairo_t *
cairo_reference (cairo_t *cr);
void
@ -224,7 +260,7 @@ cairo_pop_group (cairo_t *cr);
/* Modify state */
typedef enum cairo_operator {
typedef enum _cairo_operator {
CAIRO_OPERATOR_CLEAR,
CAIRO_OPERATOR_SOURCE,
@ -267,6 +303,29 @@ cairo_set_source_surface (cairo_t *cr,
void
cairo_set_tolerance (cairo_t *cr, double tolerance);
/**
* cairo_antialias_t:
* @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for
* the subsystem and target device
* @CAIRO_ANTIALIAS_NONE: Use a bilevel alpha mask
* @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using
* shades of gray for black text on a white background, for example).
* @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking
* advantage of the order of subpixel elements on devices
* such as LCD panels
*
* Specifies the type of antialiasing to do when rendering text or shapes.
**/
typedef enum _cairo_antialias {
CAIRO_ANTIALIAS_DEFAULT,
CAIRO_ANTIALIAS_NONE,
CAIRO_ANTIALIAS_GRAY,
CAIRO_ANTIALIAS_SUBPIXEL
} cairo_antialias_t;
void
cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias);
/**
* cairo_fill_rule_t
* @CAIRO_FILL_RULE_WINDING: If the path crosses the ray from
@ -288,7 +347,7 @@ cairo_set_tolerance (cairo_t *cr, double tolerance);
* (Note that filling is not actually implemented in this way. This
* is just a description of the rule that is applied.)
**/
typedef enum cairo_fill_rule {
typedef enum _cairo_fill_rule {
CAIRO_FILL_RULE_WINDING,
CAIRO_FILL_RULE_EVEN_ODD
} cairo_fill_rule_t;
@ -308,7 +367,7 @@ cairo_set_line_width (cairo_t *cr, double width);
*
* enumeration for style of line-endings
**/
typedef enum cairo_line_cap {
typedef enum _cairo_line_cap {
CAIRO_LINE_CAP_BUTT,
CAIRO_LINE_CAP_ROUND,
CAIRO_LINE_CAP_SQUARE
@ -317,7 +376,7 @@ typedef enum cairo_line_cap {
void
cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap);
typedef enum cairo_line_join {
typedef enum _cairo_line_join {
CAIRO_LINE_JOIN_MITER,
CAIRO_LINE_JOIN_ROUND,
CAIRO_LINE_JOIN_BEVEL
@ -628,17 +687,138 @@ typedef struct {
double max_y_advance;
} cairo_font_extents_t;
typedef enum cairo_font_slant {
typedef enum _cairo_font_slant {
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_SLANT_ITALIC,
CAIRO_FONT_SLANT_OBLIQUE
} cairo_font_slant_t;
typedef enum cairo_font_weight {
typedef enum _cairo_font_weight {
CAIRO_FONT_WEIGHT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD
} cairo_font_weight_t;
/**
* cairo_subpixel_order_t:
* @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for
* for the target device
* @CAIRO_SUBPIXEL_ORDER_RGB: Subpixel elements are arranged horizontally
* with red at the left
* @CAIRO_SUBPIXEL_ORDER_BGR: Subpixel elements are arranged horizontally
* with blue at the left
* @CAIRO_SUBPIXEL_ORDER_VRGB: Subpixel elements are arranged vertically
* with red at the top
* @CAIRO_SUBPIXEL_ORDER_VBGR: Subpixel elements are arranged vertically
* with blue at the top
*
* The subpixel order specifies the order of color elements within
* each pixel on the display device when rendering with an
* antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
**/
typedef enum _cairo_subpixel_order {
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_SUBPIXEL_ORDER_RGB,
CAIRO_SUBPIXEL_ORDER_BGR,
CAIRO_SUBPIXEL_ORDER_VRGB,
CAIRO_SUBPIXEL_ORDER_VBGR
} cairo_subpixel_order_t;
/**
* cairo_hint_style_t:
* @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for
* for font backend and target device
* @CAIRO_HINT_STYLE_NONE: Do not hint outlines
* @CAIRO_HINT_STYLE_SLIGHT: Hint outlines slightly to improve
* contrast while retaining good fidelity to the original
* shapes.
* @CAIRO_HINT_STYLE_MEDIUM: Hint outlines with medium strength
* giving a compromise between fidelity to the original shapes
* and contrast
* @CAIRO_HINT_STYLE_FULL: Hint outlines to maximize contrast
*
* Specifies the type of hinting to do on font outlines. Hinting
* is the process of fitting outlines to the pixel grid in order
* to improve the appearance of the result. Since hinting outlines
* involves distorting them, it also reduces the faithfulness
* to the original outline shapes. Not all of the outline hinting
* styles are supported by all font backends.
*/
typedef enum _cairo_hint_style {
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_STYLE_NONE,
CAIRO_HINT_STYLE_SLIGHT,
CAIRO_HINT_STYLE_MEDIUM,
CAIRO_HINT_STYLE_FULL
} cairo_hint_style_t;
/**
* cairo_hint_metrics_t:
* @CAIRO_HINT_METRICS_DEFAULT: Hint metrics in the default
* manner for the font backend and target device
* @CAIRO_HINT_METRICS_OFF: Do not hint font metrics
* @CAIRO_HINT_METRICS_ON: Hint font metrics
*
* Specifies whether to hint font metrics; hinting font metrics
* means quantizing them so that they are integer values in
* device space. Doing this improves the consistency of
* letter and line spacing, however it also means that text
* will be laid out differently at different zoom factors.
*/
typedef enum _cairo_hint_metrics {
CAIRO_HINT_METRICS_DEFAULT,
CAIRO_HINT_METRICS_OFF,
CAIRO_HINT_METRICS_ON
} cairo_hint_metrics_t;
typedef struct _cairo_font_options cairo_font_options_t;
cairo_font_options_t *
cairo_font_options_create (void);
cairo_font_options_t *
cairo_font_options_copy (const cairo_font_options_t *original);
void
cairo_font_options_destroy (cairo_font_options_t *options);
cairo_status_t
cairo_font_options_status (cairo_font_options_t *options);
void
cairo_font_options_merge (cairo_font_options_t *options,
const cairo_font_options_t *other);
cairo_bool_t
cairo_font_options_equal (const cairo_font_options_t *options,
const cairo_font_options_t *other);
unsigned long
cairo_font_options_hash (const cairo_font_options_t *options);
void
cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias);
cairo_antialias_t
cairo_font_options_get_antialias (const cairo_font_options_t *options);
void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order);
cairo_subpixel_order_t
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options);
void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style);
cairo_hint_style_t
cairo_font_options_get_hint_style (const cairo_font_options_t *options);
void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics);
cairo_hint_metrics_t
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options);
/* This interface is for dealing with text as text, not caring about the
font object inside the the cairo_t. */
@ -659,6 +839,14 @@ void
cairo_get_font_matrix (cairo_t *cr,
cairo_matrix_t *matrix);
void
cairo_set_font_options (cairo_t *cr,
const cairo_font_options_t *options);
void
cairo_get_font_options (cairo_t *cr,
cairo_font_options_t *options);
void
cairo_show_text (cairo_t *cr, const char *utf8);
@ -694,12 +882,15 @@ cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs);
/* Generic identifier for a font style */
void
cairo_font_face_t *
cairo_font_face_reference (cairo_font_face_t *font_face);
void
cairo_font_face_destroy (cairo_font_face_t *font_face);
cairo_status_t
cairo_font_face_status (cairo_font_face_t *font_face);
void *
cairo_font_face_get_user_data (cairo_font_face_t *font_face,
const cairo_user_data_key_t *key);
@ -713,17 +904,21 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
/* Portable interface to general font features. */
cairo_scaled_font_t *
cairo_scaled_font_create (cairo_font_face_t *font_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm);
cairo_scaled_font_create (cairo_font_face_t *font_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
const cairo_font_options_t *options);
void
cairo_scaled_font_t *
cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font);
void
cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
cairo_status_t
cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents);
@ -744,6 +939,9 @@ cairo_get_source (cairo_t *cr);
double
cairo_get_tolerance (cairo_t *cr);
cairo_antialias_t
cairo_get_antialias (cairo_t *cr);
void
cairo_get_current_point (cairo_t *cr, double *x, double *y);
@ -767,8 +965,6 @@ cairo_get_miter_limit (cairo_t *cr);
void
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix);
/* XXX: Need to decide the memory management semantics of this
function. Should it reference the surface again? */
cairo_surface_t *
cairo_get_target (cairo_t *cr);
@ -830,14 +1026,16 @@ cairo_get_target (cairo_t *cr);
* cairo_path_destroy (path);
* </programlisting></informalexample>
*/
typedef enum _cairo_path_data_type {
CAIRO_PATH_MOVE_TO,
CAIRO_PATH_LINE_TO,
CAIRO_PATH_CURVE_TO,
CAIRO_PATH_CLOSE_PATH
} cairo_path_data_type_t;
typedef union {
struct {
enum {
CAIRO_PATH_MOVE_TO,
CAIRO_PATH_LINE_TO,
CAIRO_PATH_CURVE_TO,
CAIRO_PATH_CLOSE_PATH
} type;
cairo_path_data_type_t type;
int length;
} header;
struct {
@ -847,6 +1045,9 @@ typedef union {
/**
* cairo_path_t:
* @status: the current error status
* @data: the elements in the path
* @num_data: the number of elements in the data array
*
* A data structure for holding a path. This data structure serves as
* the return value for cairo_copy_path_data() and
@ -862,6 +1063,7 @@ typedef union {
* includes both headers and coordinates for each portion.
**/
typedef struct cairo_path {
cairo_status_t status;
cairo_path_data_t *data;
int num_data;
} cairo_path_t;
@ -885,57 +1087,55 @@ cairo_status_t
cairo_status (cairo_t *cr);
const char *
cairo_status_string (cairo_t *cr);
cairo_status_to_string (cairo_status_t status);
/* Surface manipulation */
/**
* cairo_format_t
* @CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with
* alpha in the upper 8 bits, then red, then green, then blue.
* The 32-bit quantities are stored native-endian. Pre-multiplied
* alpha is used. (That is, 50% transparent red is 0x80800000,
* not 0x80ff0000.)
* @CAIRO_FORMAT_RGB24: each pixel is a 32-bit quantity, with
* the upper 8 bits unused. Red, Green, and Blue are stored
* in the remaining 24 bits in that order.
* @CAIRO_FORMAT_A8: each pixel is a 8-bit quantity holding
* an alpha value.
* @CAIRO_FORMAT_A1: each pixel is a 1-bit quantity holding
* an alpha value. Pixels are packed together into 32-bit
* quantities. The ordering of the bits matches the
* endianess of the platform. On a big-endian machine, the
* first pixel is in the uppermost bit, on a little-endian
* machine the first pixel is in the least-significant bit.
* cairo_content_t
* @CAIRO_CONTENT_COLOR: The surface will hold color content only.
* @CAIRO_CONTENT_ALPHA: The surface will hold alpha content only.
* @CAIRO_CONTENT_COLOR_ALPHA: The surface will hold color and alpha content.
*
* #cairo_format_t is used to identify the memory format of
* image data.
* @cairo_content_t is used to describe the content that a surface will
* contain, whether color information, alpha information (translucence
* vs. opacity), or both.
*
* Note: The large values here are designed to keep cairo_content_t
* values distinct from cairo_format_t values so that the
* implementation can detect the error if users confuse the two types.
*/
typedef enum cairo_format {
CAIRO_FORMAT_ARGB32,
CAIRO_FORMAT_RGB24,
CAIRO_FORMAT_A8,
CAIRO_FORMAT_A1
} cairo_format_t;
typedef enum _cairo_content {
CAIRO_CONTENT_COLOR = 0x1000,
CAIRO_CONTENT_ALPHA = 0x2000,
CAIRO_CONTENT_COLOR_ALPHA = 0x3000
} cairo_content_t;
#define CAIRO_CONTENT_VALID(content) ((content) && \
(((content) & ~(CAIRO_CONTENT_COLOR | \
CAIRO_CONTENT_ALPHA | \
CAIRO_CONTENT_COLOR_ALPHA))\
== 0))
/* XXX: I want to remove this function, (replace with
cairo_begin_group and friends). */
cairo_surface_t *
cairo_surface_create_similar (cairo_surface_t *other,
cairo_format_t format,
cairo_surface_create_similar (cairo_surface_t *other,
cairo_content_t content,
int width,
int height);
void
cairo_surface_t *
cairo_surface_reference (cairo_surface_t *surface);
void
cairo_surface_destroy (cairo_surface_t *surface);
cairo_status_t
cairo_surface_status (cairo_surface_t *surface);
void
cairo_surface_finish (cairo_surface_t *surface);
#ifdef CAIRO_HAS_PNG_FUNCTIONS
#if CAIRO_HAS_PNG_FUNCTIONS
cairo_status_t
cairo_surface_write_to_png (cairo_surface_t *surface,
@ -958,6 +1158,23 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
void *user_data,
cairo_destroy_func_t destroy);
void
cairo_surface_get_font_options (cairo_surface_t *surface,
cairo_font_options_t *options);
void
cairo_surface_flush (cairo_surface_t *surface);
void
cairo_surface_mark_dirty (cairo_surface_t *surface);
void
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
int x,
int y,
int width,
int height);
void
cairo_surface_set_device_offset (cairo_surface_t *surface,
double x_offset,
@ -965,6 +1182,38 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
/* Image-surface functions */
/**
* cairo_format_t
* @CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with
* alpha in the upper 8 bits, then red, then green, then blue.
* The 32-bit quantities are stored native-endian. Pre-multiplied
* alpha is used. (That is, 50% transparent red is 0x80800000,
* not 0x80ff0000.)
* @CAIRO_FORMAT_RGB24: each pixel is a 32-bit quantity, with
* the upper 8 bits unused. Red, Green, and Blue are stored
* in the remaining 24 bits in that order.
* @CAIRO_FORMAT_A8: each pixel is a 8-bit quantity holding
* an alpha value.
* @CAIRO_FORMAT_A1: each pixel is a 1-bit quantity holding
* an alpha value. Pixels are packed together into 32-bit
* quantities. The ordering of the bits matches the
* endianess of the platform. On a big-endian machine, the
* first pixel is in the uppermost bit, on a little-endian
* machine the first pixel is in the least-significant bit.
*
* #cairo_format_t is used to identify the memory format of
* image data.
*/
typedef enum _cairo_format {
CAIRO_FORMAT_ARGB32,
CAIRO_FORMAT_RGB24,
CAIRO_FORMAT_A8,
CAIRO_FORMAT_A1
} cairo_format_t;
#define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
(format) <= CAIRO_FORMAT_A1)
cairo_surface_t *
cairo_image_surface_create (cairo_format_t format,
int width,
@ -983,7 +1232,7 @@ cairo_image_surface_get_width (cairo_surface_t *surface);
int
cairo_image_surface_get_height (cairo_surface_t *surface);
#ifdef CAIRO_HAS_PNG_FUNCTIONS
#if CAIRO_HAS_PNG_FUNCTIONS
cairo_surface_t *
cairo_image_surface_create_from_png (const char *filename);
@ -995,6 +1244,14 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
#endif
/* Pattern creation functions */
cairo_pattern_t *
cairo_pattern_create_rgb (double red, double green, double blue);
cairo_pattern_t *
cairo_pattern_create_rgba (double red, double green, double blue,
double alpha);
cairo_pattern_t *
cairo_pattern_create_for_surface (cairo_surface_t *surface);
@ -1006,44 +1263,47 @@ cairo_pattern_t *
cairo_pattern_create_radial (double cx0, double cy0, double radius0,
double cx1, double cy1, double radius1);
void
cairo_pattern_t *
cairo_pattern_reference (cairo_pattern_t *pattern);
void
cairo_pattern_destroy (cairo_pattern_t *pattern);
cairo_status_t
cairo_pattern_status (cairo_pattern_t *pattern);
void
cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
double offset,
double red, double green, double blue);
cairo_status_t
void
cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
double offset,
double red, double green, double blue,
double alpha);
cairo_status_t
void
cairo_pattern_set_matrix (cairo_pattern_t *pattern,
const cairo_matrix_t *matrix);
cairo_status_t
void
cairo_pattern_get_matrix (cairo_pattern_t *pattern,
cairo_matrix_t *matrix);
typedef enum {
typedef enum _cairo_extend {
CAIRO_EXTEND_NONE,
CAIRO_EXTEND_REPEAT,
CAIRO_EXTEND_REFLECT
} cairo_extend_t;
cairo_status_t
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend);
cairo_extend_t
cairo_pattern_get_extend (cairo_pattern_t *pattern);
typedef enum {
typedef enum _cairo_filter {
CAIRO_FILTER_FAST,
CAIRO_FILTER_GOOD,
CAIRO_FILTER_BEST,
@ -1052,7 +1312,7 @@ typedef enum {
CAIRO_FILTER_GAUSSIAN
} cairo_filter_t;
cairo_status_t
void
cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
cairo_filter_t
@ -1139,7 +1399,6 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix,
#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix
#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target
#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status
#define cairo_get_status_string cairo_get_status_string_REPLACED_BY_cairo_status_string
#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform
#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size
#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face
@ -1188,6 +1447,8 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix,
#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,252 +0,0 @@
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-gstate-private.h cairo/src/cairo-gstate-private.h
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-gstate-private.h 2005-05-06 21:55:23.000000000 -0700
+++ cairo/src/cairo-gstate-private.h 2005-06-01 22:19:22.000000000 -0700
@@ -52,6 +52,8 @@
double *dash;
int num_dashes;
double dash_offset;
+ double max_dash_length;
+ double fraction_dash_lit;
char *font_family; /* NULL means CAIRO_FONT_FAMILY_DEFAULT; */
cairo_font_slant_t font_slant;
Only in cairo/src: cairo-gstate-private.h~
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-gstate.c cairo/src/cairo-gstate.c
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-gstate.c 2005-05-12 10:59:01.000000000 -0700
+++ cairo/src/cairo-gstate.c 2005-06-01 22:15:34.000000000 -0700
@@ -101,6 +101,8 @@
gstate->dash = NULL;
gstate->num_dashes = 0;
gstate->dash_offset = 0.0;
+ gstate->max_dash_length = 0.0;
+ gstate->fraction_dash_lit = 0.0;
gstate->scaled_font = NULL;
gstate->font_face = NULL;
@@ -509,6 +511,9 @@
cairo_status_t
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
{
+ double length = 0.0, lit = 0.0;
+ int i;
+
if (gstate->dash) {
free (gstate->dash);
gstate->dash = NULL;
@@ -521,6 +526,16 @@
gstate->num_dashes = 0;
return CAIRO_STATUS_NO_MEMORY;
}
+
+ gstate->max_dash_length = 0.0;
+ for (i = 0; i < num_dashes; i++) {
+ gstate->max_dash_length = MAX(dash[i], gstate->max_dash_length);
+
+ if (!(i & 1))
+ lit += dash[i];
+ length += dash[i];
+ }
+ gstate->fraction_dash_lit = lit/length;
}
memcpy (gstate->dash, dash, gstate->num_dashes * sizeof (double));
@@ -954,11 +969,30 @@
return status;
}
+static cairo_bool_t
+_dashes_invisible (cairo_gstate_t *gstate)
+{
+ if (gstate->dash) {
+ double min, max;
+
+ _cairo_matrix_compute_expansion_factors (&gstate->ctm, &min, &max);
+
+ /* Quick and dirty applicaton of Nyquist sampling limit */
+
+ if (min * gstate->max_dash_length < 0.5f)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
cairo_status_t
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
cairo_status_t status;
cairo_traps_t traps;
+ double *dash = NULL;
+ double alpha = 0.0;
if (gstate->surface->level != gstate->surface_level)
return CAIRO_STATUS_BAD_NESTING;
@@ -966,15 +1000,21 @@
if (gstate->line_width <= 0.0)
return CAIRO_STATUS_SUCCESS;
+ if (_dashes_invisible(gstate)) {
+ dash = gstate->dash;
+ gstate->dash = NULL;
+
+ /* alpha = gstate->alpha; */
+ /* gstate->alpha *= gstate->fraction_dash_lit; */
+ }
+
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
_cairo_traps_init (&traps);
status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps);
- if (status) {
- _cairo_traps_fini (&traps);
- return status;
- }
+ if (status)
+ goto BAIL;
_cairo_gstate_clip_and_composite_trapezoids (gstate,
gstate->source,
@@ -982,9 +1022,15 @@
gstate->surface,
&traps);
+BAIL:
_cairo_traps_fini (&traps);
- return CAIRO_STATUS_SUCCESS;
+ if (dash) {
+ gstate->dash = dash;
+ /* gstate->alpha = alpha; */
+ }
+
+ return status;
}
cairo_status_t
@@ -1514,7 +1560,13 @@
cairo_status_t status;
cairo_traps_t traps;
cairo_box_t extents;
-
+ double *dash = NULL;
+
+ if (_dashes_invisible(gstate)) {
+ dash = gstate->dash;
+ gstate->dash = NULL;
+ }
+
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
_cairo_traps_init (&traps);
@@ -1535,6 +1587,9 @@
BAIL:
_cairo_traps_fini (&traps);
+
+ if (dash)
+ gstate->dash = dash;
return status;
}
Only in cairo/src: cairo-gstate.c~
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-matrix.c cairo/src/cairo-matrix.c
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-matrix.c 2005-05-09 08:50:27.000000000 -0700
+++ cairo/src/cairo-matrix.c 2005-06-01 22:19:54.000000000 -0700
@@ -559,6 +559,29 @@
return CAIRO_STATUS_SUCCESS;
}
+/* Compute the min/max expansion factors. See the comment in
+ * cairo-pen.c for the derivation */
+cairo_status_t
+_cairo_matrix_compute_expansion_factors (const cairo_matrix_t *matrix,
+ double *min, double *max)
+{
+ double a = matrix->xx, b = matrix->yx;
+ double c = matrix->xy, d = matrix->yy;
+
+ double i = a*a + c*c;
+ double j = b*b + d*d;
+
+ double f = 0.5 * (i + j);
+ double g = 0.5 * (i - j);
+ double h = a*b + c*d;
+
+ *max = sqrt (f + sqrt (g*g+h*h));
+
+ *min = sqrt (f - sqrt (g*g+h*h));
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
cairo_bool_t
_cairo_matrix_is_integer_translation(const cairo_matrix_t *mat,
int *itx, int *ity)
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-pen.c cairo/src/cairo-pen.c
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-pen.c 2005-05-06 21:55:23.000000000 -0700
+++ cairo/src/cairo-pen.c 2005-06-01 22:18:51.000000000 -0700
@@ -374,32 +374,15 @@
double radius,
cairo_matrix_t *matrix)
{
- double a = matrix->xx, b = matrix->yx;
- double c = matrix->xy, d = matrix->yy;
+ double min, max, major_axis;
+ int num_vertices;
- double i = a*a + c*c;
- double j = b*b + d*d;
-
- double f = 0.5 * (i + j);
- double g = 0.5 * (i - j);
- double h = a*b + c*d;
-
- /*
- * compute major and minor axes lengths for
- * a pen with the specified radius
- */
-
- double major_axis = radius * sqrt (f + sqrt (g*g+h*h));
-
- /*
- * we don't need the minor axis length, which is
- * double min = radius * sqrt (f - sqrt (g*g+h*h));
- */
+ _cairo_matrix_compute_expansion_factors (matrix, &min, &max);
+ major_axis = radius * max;
/*
* compute number of vertices needed
*/
- int num_vertices;
/* Where tolerance / M is > 1, we use 4 points */
if (tolerance >= major_axis) {
Only in cairo/src: cairo-pen.c~
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-wideint.h cairo/src/cairo-wideint.h
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairo-wideint.h 2005-05-10 14:55:37.000000000 -0700
+++ cairo/src/cairo-wideint.h 2005-06-01 22:07:43.000000000 -0700
@@ -45,7 +45,7 @@
#elif HAVE_SYS_INT_TYPES_H
# include <sys/int_types.h>
#else
-#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
+# include "mozstdint.h"
#endif
/*
diff -ru ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairoint.h cairo/src/cairoint.h
--- ../../../../../cairo-cvs/dist/cairo-0.5.0/src/cairoint.h 2005-05-17 06:17:45.000000000 -0700
+++ cairo/src/cairoint.h 2005-06-01 22:19:46.000000000 -0700
@@ -1638,6 +1638,9 @@
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major);
+cairo_private cairo_status_t
+_cairo_matrix_compute_expansion_factors (const cairo_matrix_t *matrix, double *min, double *max);
+
cairo_private cairo_bool_t
_cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix,
int *itx, int *ity);
Only in cairo/src: cairoint.h~

Просмотреть файл

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.la
*.lo
*.loT
.libs
.deps

Просмотреть файл

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.la
*.lo
*.loT
.libs
.deps

Просмотреть файл

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.la
*.lo
*.loT
.libs
.deps

Просмотреть файл

@ -0,0 +1,38 @@
.\"
.\"
.de TQ
.br
.ns
.TP
\\$1
..
.TH GLITZ 3 "Version 1.0"
.SH NAME
GLITZ \- OpenGL image compositing library
.SH SYNOPSIS
.nf
.B #include <glitz.h>
.fi
.SH DESCRIPTION
Glitz is an OpenGL image compositing library. Glitz provides
Porter/Duff compositing of images and implicit mask generation for
geometric primitives including trapezoids, triangles, and rectangles.
The semantics of glitz are designed to precisely match the
specification of the X Render extension. Glitz does not only implement
X Render features like component alpha and image transformations, but
also support for additional features like convolution filters and color
gradients, which are not currently part of the X Render specification.
The performance and capabilities of glitz are much dependent on
graphics hardware. Glitz does not in any way handle software
fall-backs when graphics hardware is insufficient. However, glitz
will report if any requested operation cannot be carried out by
graphics hardware, hence making a higher level software layer
responsible for appropriate actions.
.SH AUTHOR
David Reveman

Просмотреть файл

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.la
*.lo
*.loT
.libs
.deps

Просмотреть файл

@ -0,0 +1,26 @@
.\"
.\"
.de TQ
.br
.ns
.TP
\\$1
..
.TH GLITZ-GLX 3 "Version 1.0"
.SH NAME
GLITZ-GLX \- GLX interface to glitz
.SH SYNOPSIS
.nf
.B #include <glitz-glx.h>
.fi
.SH DESCRIPTION
GLX interface to glitz.
.SH AUTHOR
David Reveman
.SH "SEE ALSO"
.BR GLITZ (3)

Просмотреть файл

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.la
*.lo
*.loT
.libs
.deps

Просмотреть файл

Просмотреть файл

@ -1,3 +1,45 @@
Snapshot 0.1.6 (2005-07-28 Carl Worth <cworth@cworth.org>)
==========================================================
Behavioral changes
------------------
Clips are changed to only affect destination operands, not
sources. This gives the desired behavior for cairo. If the X server's
Render implementation wants to use pixman it will have to select
source clipping, (presumably through a new API call that we can add at
that point).
Bug fixes
---------
Fix leak of the clip region associated with an image in
pixman_image_destroy.
Fix units for stride return to be FbStip-sized, (this bug was causing
non antialiased text in cairo to appear as garbage).
Other changes
-------------
The implementation has been merged considerably with xserver/fb. Most
of the merge was just name changes, but there were likely some bug
fixes or performance improvements in there as well.
Snapshot 0.1.5 (2005-05-18 Carl Worth <cworth@cworth.org>)
==========================================================
Bug fixes
---------
Fix confusion of depth and bpp which was causing cairo to crash on
some X servers.
Properly declare pixman_fixed16_16_t as int32_t which fixes
compilation failures on some platforms.
Fix to find inttypes.h on AIX.
Fix bug in compositing when the source image has no alpha channel.
Some fixes to the clipping code.
Fix memory leak when asked to draw a degenerate trapezoid list.
Snapshot 0.1.4 (2005-03-07 Carl Worth <cworth@cworth.org>)
==========================================================
API Addition

Просмотреть файл

@ -47,20 +47,14 @@ MODULE = libpixman
LIBRARY_NAME = mozlibpixman
LIBXUL_LIBRARY = 1
ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
ifeq ($(MOZ_OPTIMIZE),1)
USE_STATIC_VC71_LIB = 1
endif
endif
CSRCS = \
fbcompose.c \
fbedge.c \
fbtrap.c \
ic.c \
icblt.c \
icbltone.c \
iccolor.c \
iccompose.c \
icformat.c \
icimage.c \
icpixels.c \
@ -74,7 +68,12 @@ CSRCS = \
renderedge.c \
$(NULL)
EXPORTS = pixman.h mozstdint.h
ifdef MOZ_X11
#CSRCS += fbmmx.c
#DEFINES += -DUSE_MMX
endif
EXPORTS = pixman.h pixman-remap.h mozstdint.h
LOCAL_INCLUDES = -I$(srcdir)
@ -84,9 +83,7 @@ FORCE_USE_PIC = 1
include $(topsrcdir)/config/rules.mk
ifeq ($(USE_STATIC_VC71_LIB),1)
libs:: $(srcdir)/pixman-vc71.lib
cp $(srcdir)/pixman-vc71.lib $(LIBRARY)
$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
ifdef MOZ_X11
#CFLAGS += -mmmx -msse -Winline --param inline-unit-growth=10000 --param large-function-growth=10000
endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: fbedge.c,v 1.3 2005/06/04 07:03:28 vladimir%pobox.com Exp $
* $Id: fbedge.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
@ -22,35 +22,11 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include "pixman-xserver-compat.h"
#ifdef RENDER
/*
* 8 bit alpha
*/
#define N_BITS 8
#define rasterizeEdges fbRasterizeEdges8
#define DefineAlpha(line,x) \
CARD8 *__ap = (CARD8 *) line + (x)
#define StepAlpha __ap++
#define AddAlpha(a) { \
CARD16 __a = a + *__ap; \
*__ap = ((CARD8) ((__a) | (0 - ((__a) >> 8)))); \
}
#include "fbedgeimp.h"
#undef AddAlpha
#undef StepAlpha
#undef DefineAlpha
#undef rasterizeEdges
#undef N_BITS
/*
* 4 bit alpha
*/
@ -100,6 +76,208 @@
#undef rasterizeEdges
#undef N_BITS
/*
* 8 bit alpha
*/
static INLINE CARD8
clip255 (int x)
{
if (x > 255) return 255;
return x;
}
static INLINE void
add_saturate_8 (CARD8 *buf, int value, int length)
{
while (length--)
{
*buf = clip255 (*buf + value);
buf++;
}
}
/*
* We want to detect the case where we add the same value to a long
* span of pixels. The triangles on the end are filled in while we
* count how many sub-pixel scanlines contribute to the middle section.
*
* +--------------------------+
* fill_height =| \ /
* +------------------+
* |================|
* fill_start fill_end
*/
static void
fbRasterizeEdges8 (FbBits *buf,
int width,
int stride,
RenderEdge *l,
RenderEdge *r,
xFixed t,
xFixed b)
{
xFixed y = t;
FbBits *line;
int fill_start = -1, fill_end = -1;
int fill_size = 0;
line = buf + xFixedToInt (y) * stride;
for (;;)
{
CARD8 *ap = (CARD8 *) line;
xFixed lx, rx;
int lxi, rxi;
/* clip X */
lx = l->x;
if (lx < 0)
lx = 0;
rx = r->x;
if (xFixedToInt (rx) >= width)
rx = IntToxFixed (width);
/* Skip empty (or backwards) sections */
if (rx > lx)
{
int lxs, rxs;
/* Find pixel bounds for span. */
lxi = xFixedToInt (lx);
rxi = xFixedToInt (rx);
/* Sample coverage for edge pixels */
lxs = RenderSamplesX (lx, 8);
rxs = RenderSamplesX (rx, 8);
/* Add coverage across row */
if (lxi == rxi)
{
ap[lxi] = clip255 (ap[lxi] + rxs - lxs);
}
else
{
ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs);
/* Move forward so that lxi/rxi is the pixel span */
lxi++;
/* Don't bother trying to optimize the fill unless
* the span is longer than 4 pixels. */
if (rxi - lxi > 4)
{
if (fill_start < 0)
{
fill_start = lxi;
fill_end = rxi;
fill_size++;
}
else
{
if (lxi >= fill_end || rxi < fill_start)
{
/* We're beyond what we saved, just fill it */
add_saturate_8 (ap + fill_start,
fill_size * N_X_FRAC(8),
fill_end - fill_start);
fill_start = lxi;
fill_end = rxi;
fill_size = 1;
}
else
{
/* Update fill_start */
if (lxi > fill_start)
{
add_saturate_8 (ap + fill_start,
fill_size * N_X_FRAC(8),
lxi - fill_start);
fill_start = lxi;
}
else if (lxi < fill_start)
{
add_saturate_8 (ap + lxi, N_X_FRAC(8),
fill_start - lxi);
}
/* Update fill_end */
if (rxi < fill_end)
{
add_saturate_8 (ap + rxi,
fill_size * N_X_FRAC(8),
fill_end - rxi);
fill_end = rxi;
}
else if (fill_end < rxi)
{
add_saturate_8 (ap + fill_end,
N_X_FRAC(8),
rxi - fill_end);
}
fill_size++;
}
}
}
else
{
add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
}
/* Do not add in a 0 alpha here. This check is
* necessary to avoid a buffer overrun, (when rx
* is exactly on a pixel boundary). */
if (rxs)
ap[rxi] = clip255 (ap[rxi] + rxs);
}
}
if (y == b) {
/* We're done, make sure we clean up any remaining fill. */
if (fill_start != fill_end) {
if (fill_size == N_Y_FRAC(8))
{
memset (ap + fill_start, 0xff, fill_end - fill_start);
}
else
{
add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
fill_end - fill_start);
}
}
break;
}
if (xFixedFrac (y) != Y_FRAC_LAST(8))
{
RenderEdgeStepSmall (l);
RenderEdgeStepSmall (r);
y += STEP_Y_SMALL(8);
}
else
{
RenderEdgeStepBig (l);
RenderEdgeStepBig (r);
y += STEP_Y_BIG(8);
if (fill_start != fill_end)
{
if (fill_size == N_Y_FRAC(8))
{
memset (ap + fill_start, 0xff, fill_end - fill_start);
}
else
{
add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
fill_end - fill_start);
}
fill_start = fill_end = -1;
fill_size = 0;
}
line += stride;
}
}
}
void
fbRasterizeEdges (FbBits *buf,
int bpp,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,228 @@
/*
* Copyright © 2004 Red Hat, Inc.
* Copyright © 2005 Trolltech AS
*
* 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 and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Red Hat not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Red Hat makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Author: Søren Sandmann (sandmann@redhat.com)
* Lars Knoll (lars@trolltech.com)
*
* Based on work by Owen Taylor
*/
#ifdef USE_MMX
#if !defined(__amd64__) && !defined(__x86_64__)
Bool fbHaveMMX(void);
#else
#define fbHaveMMX() TRUE
#endif
#else
#define fbHaveMMX() FALSE
#endif
#ifdef USE_MMX
void fbComposeSetupMMX(void);
void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrcAdd_8888x8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolidMask_nx8888x8888Cmmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolidMask_nx8x8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrcAdd_8000x8000mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrc_8888RevNPx8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrc_8888RevNPx0565mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolid_nx8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolid_nx0565mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSolidMask_nx8x0565mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrc_x888x8x8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
Bool fbCopyAreammx (FbPixels *pSrc,
FbPixels *pDst,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height);
void fbCompositeCopyAreammx (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
Bool fbSolidFillmmx (FbPixels *pDraw,
int x,
int y,
int width,
int height,
FbBits xor);
#endif /* USE_MMX */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,356 @@
/*
* $Id: fbpict.h,v 1.1 2005/08/20 05:34:02 vladimir%pobox.com Exp $
*
* Copyright © 2000 Keith Packard
* 2005 Lars Knoll & Zack Rusin, Trolltech
*
* 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 and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef _FBPICT_H_
#define _FBPICT_H_
#include "pixman-xserver-compat.h"
#include "renderedge.h"
#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
#define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
/*
* There are two ways of handling alpha -- either as a single unified value or
* a separate value for each component, hence each macro must have two
* versions. The unified alpha version has a 'U' at the end of the name,
* the component version has a 'C'. Similarly, functions which deal with
* this difference will have two versions using the same convention.
*/
#define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
#define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
#define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
#define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
#define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
FbIntMult(FbGet8(x,i),ax,(v))),\
(CARD32) ((CARD8) ((t) | \
(0 - ((t) >> 8)))) << (i))
#define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
#define Alpha(x) ((x) >> 24)
#define Red(x) (((x) >> 16) & 0xff)
#define Green(x) (((x) >> 8) & 0xff)
#define Blue(x) ((x) & 0xff)
#define fbComposeGetSolid(pict, bits) { \
FbBits *__bits__; \
FbStride __stride__; \
int __bpp__; \
int __xoff__,__yoff__; \
\
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
switch (__bpp__) { \
case 32: \
(bits) = *(CARD32 *) __bits__; \
break; \
case 24: \
(bits) = Fetch24 ((CARD8 *) __bits__); \
break; \
case 16: \
(bits) = *(CARD16 *) __bits__; \
(bits) = cvt0565to0888(bits); \
break; \
case 8: \
(bits) = *(CARD8 *) __bits__; \
(bits) = (bits) << 24; \
break; \
case 1: \
(bits) = *(CARD32 *) __bits__; \
(bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
break; \
default: \
return; \
} \
/* manage missing src alpha */ \
if ((pict)->image_format.alphaMask == 0) \
(bits) |= 0xff000000; \
}
#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
FbBits *__bits__; \
FbStride __stride__; \
int __bpp__; \
int __xoff__,__yoff__; \
\
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
(stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
(line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
}
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
(((s) >> 5) & 0x07e0) | \
(((s) >> 8) & 0xf800))
#define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
#if IMAGE_BYTE_ORDER == MSBFirst
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
((*((CARD16 *) (a)) << 8) | *((a)+2)))
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
((*(a) = (CARD8) ((v) >> 16)), \
(*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
(*((a)+2) = (CARD8) (v))))
#else
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
((*((CARD16 *) (a))) | (*((a)+2) << 16)))
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
((*(a) = (CARD8) (v)), \
(*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
((*((CARD16 *) (a)) = (CARD16) (v)),\
(*((a)+2) = (CARD8) ((v) >> 16))))
#endif
/*
The methods below use some tricks to be able to do two color
components at the same time.
*/
/*
x_c = (x_c * a) / 255
*/
#define FbByteMul(x, a) do { \
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
t &= 0xff00ff; \
\
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
x = (x + ((x >> 8) & 0xff00ff)); \
x &= 0xff00ff00; \
x += t; \
} while (0)
/*
x_c = (x_c * a) / 255 + y
*/
#define FbByteMulAdd(x, a, y) do { \
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
t &= 0xff00ff; \
t += y & 0xff00ff; \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
t &= 0xff00ff; \
\
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
x &= 0xff00ff; \
x += (y >> 8) & 0xff00ff; \
x |= 0x1000100 - ((t >> 8) & 0xff00ff); \
x &= 0xff00ff; \
x <<= 8; \
x += t; \
} while (0)
/*
x_c = (x_c * a + y_c * b) / 255
*/
#define FbByteAddMul(x, a, y, b) do { \
CARD32 t; \
CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
r += (r >> 8); \
r >>= 8; \
\
t = (x & 0xff00) * a + (y & 0xff00) * b + 0x8000; \
t += (t >> 8); \
t >>= 16; \
\
t |= r << 16; \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
t &= 0xff00ff; \
t <<= 8; \
\
r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
r += (r >> 8); \
r >>= 8; \
\
x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
x += (x >> 8); \
x >>= 8; \
x |= r << 16; \
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
x &= 0xff00ff; \
x |= t; \
} while (0)
/*
x_c = (x_c * a + y_c *b) / 256
*/
#define FbByteAddMul_256(x, a, y, b) do { \
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; \
} while (0)
/*
x_c = (x_c * a_c) / 255
*/
#define FbByteMulC(x, a) do { \
CARD32 t; \
CARD32 r = (x & 0xff) * (a & 0xff); \
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
r += 0x800080; \
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
r &= 0xff00ff; \
\
x >>= 8; \
t = (x & 0xff) * ((a >> 8) & 0xff); \
t |= (x & 0xff0000) * (a >> 24); \
t += 0x800080; \
t = t + ((t >> 8) & 0xff00ff); \
x = r | (t & 0xff00ff00); \
\
} while (0)
/*
x_c = (x_c * a) / 255 + y
*/
#define FbByteMulAddC(x, a, y) do { \
CARD32 t; \
CARD32 r = (x & 0xff) * (a & 0xff); \
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
r += 0x800080; \
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
r &= 0xff00ff; \
r += y & 0xff00ff; \
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
r &= 0xff00ff; \
\
x >>= 8; \
t = (x & 0xff) * ((a >> 8) & 0xff); \
t |= (x & 0xff0000) * (a >> 24); \
t += 0x800080; \
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
t &= 0xff00ff; \
t += (y >> 8) & 0xff00ff; \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
t &= 0xff00ff; \
x = r | (t << 8); \
} while (0)
/*
x_c = (x_c * a_c + y_c * b) / 255
*/
#define FbByteAddMulC(x, a, y, b) do { \
CARD32 t; \
CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b + 0x80; \
r += (r >> 8); \
r >>= 8; \
\
t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b + 0x8000; \
t += (t >> 8); \
t >>= 16; \
\
t |= r << 16; \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
t &= 0xff00ff; \
t <<= 8; \
\
r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
r += (r >> 8); \
r >>= 8; \
\
x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
x += (x >> 8); \
x >>= 8; \
x |= r << 16; \
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
x &= 0xff00ff; \
x |= t; \
} while (0)
/*
x_c = min(x_c + y_c, 255)
*/
#define FbByteAdd(x, y) do { \
CARD32 t; \
CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
r &= 0xff00ff; \
\
t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
r |= (t & 0xff00ff) << 8; \
x = r; \
} while (0)
#define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
#if defined(__i386__) && defined(__GNUC__)
#define FASTCALL __attribute__((regparm(3)))
#else
#define FASTCALL
#endif
#if defined(__GNUC__)
#define INLINE __inline__
#else
#define INLINE
#endif
typedef struct _FbComposeData {
CARD8 op;
PicturePtr src;
PicturePtr mask;
PicturePtr dest;
INT16 xSrc;
INT16 ySrc;
INT16 xMask;
INT16 yMask;
INT16 xDest;
INT16 yDest;
CARD16 width;
CARD16 height;
} FbComposeData;
typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
typedef struct _FbComposeFunctions {
CombineFuncU *combineU;
CombineFuncC *combineC;
CombineMaskU combineMaskU;
} FbComposeFunctions;
#endif /* _FBPICT_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,10 +22,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "icint.h"
#include "pixman-xserver-compat.h"
/*
* Example: srcX = 13 dstX = 8 (IC unit 32 dstBpp 8)
* Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
*
* **** **** **** **** **** **** **** ****
* ^
@ -34,7 +34,7 @@
* leftShift = 12
* rightShift = 20
*
* Example: srcX = 0 dstX = 8 (IC unit 32 dstBpp 8)
* Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
*
* **** **** **** **** **** **** **** ****
* ^
@ -48,16 +48,16 @@
#define LoadBits {\
if (leftShift) { \
bitsRight = *src++; \
bits = (IcStipLeft (bitsLeft, leftShift) | \
IcStipRight(bitsRight, rightShift)); \
bits = (FbStipLeft (bitsLeft, leftShift) | \
FbStipRight(bitsRight, rightShift)); \
bitsLeft = bitsRight; \
} else \
bits = *src++; \
}
#ifndef ICNOPIXADDR
#ifndef FBNOPIXADDR
#define LaneCases1(n,a) case n: (void)IcLaneCase(n,a); break
#define LaneCases1(n,a) case n: (void)FbLaneCase(n,a); break
#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a)
#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a)
#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a)
@ -67,16 +67,16 @@
#define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a)
#define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a)
#if IC_SHIFT == 6
#if FB_SHIFT == 6
#define LaneCases(a) LaneCases256(0,a)
#endif
#if IC_SHIFT == 5
#if FB_SHIFT == 5
#define LaneCases(a) LaneCases16(0,a)
#endif
#if IC_SHIFT == 6
static uint8_t const Ic8Lane[256] = {
#if FB_SHIFT == 6
static uint8_t const fb8Lane[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
@ -93,89 +93,89 @@ static uint8_t const Ic8Lane[256] = {
242, 243, 244,245,246,247,248,249,250,251,252,253,254,255,
};
static uint8_t const Ic16Lane[256] = {
static uint8_t const fb16Lane[256] = {
0x00, 0x03, 0x0c, 0x0f,
0x30, 0x33, 0x3c, 0x3f,
0xc0, 0xc3, 0xcc, 0xcf,
0xf0, 0xf3, 0xfc, 0xff,
};
static uint8_t const Ic32Lane[16] = {
static uint8_t const fb32Lane[16] = {
0x00, 0x0f, 0xf0, 0xff,
};
#endif
#if IC_SHIFT == 5
static uint8_t const Ic8Lane[16] = {
#if FB_SHIFT == 5
static uint8_t const fb8Lane[16] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
static uint8_t const Ic16Lane[16] = {
static uint8_t const fb16Lane[16] = {
0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static uint8_t const Ic32Lane[16] = {
static uint8_t const fb32Lane[16] = {
0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#endif
static const uint8_t *
IcLaneTable(int bpp)
fbLaneTable(int bpp)
{
switch (bpp) {
case 8:
return Ic8Lane;
return fb8Lane;
case 16:
return Ic16Lane;
return fb16Lane;
case 32:
return Ic32Lane;
return fb32Lane;
}
return 0;
}
#endif
void
IcBltOne (IcStip *src,
IcStride srcStride, /* IcStip units per scanline */
fbBltOne (FbStip *src,
FbStride srcStride, /* FbStip units per scanline */
int srcX, /* bit position of source */
pixman_bits_t *dst,
IcStride dstStride, /* pixman_bits_t units per scanline */
FbBits *dst,
FbStride dstStride, /* FbBits units per scanline */
int dstX, /* bit position of dest */
int dstBpp, /* bits per destination unit */
int width, /* width in bits of destination */
int height, /* height in scanlines */
pixman_bits_t fgand, /* rrop values */
pixman_bits_t fgxor,
pixman_bits_t bgand,
pixman_bits_t bgxor)
FbBits fgand, /* rrop values */
FbBits fgxor,
FbBits bgand,
FbBits bgxor)
{
const pixman_bits_t *icbits;
int pixelsPerDst; /* dst pixels per pixman_bits_t */
int unitsPerSrc; /* src patterns per IcStip */
const FbBits *fbBits;
int pixelsPerDst; /* dst pixels per FbBits */
int unitsPerSrc; /* src patterns per FbStip */
int leftShift, rightShift; /* align source with dest */
pixman_bits_t startmask, endmask; /* dest scanline masks */
IcStip bits=0, bitsLeft, bitsRight;/* source bits */
IcStip left;
pixman_bits_t mask;
FbBits startmask, endmask; /* dest scanline masks */
FbStip bits=0, bitsLeft, bitsRight;/* source bits */
FbStip left;
FbBits mask;
int nDst; /* dest longwords (w.o. end) */
int w;
int n, nmiddle;
int dstS; /* stipple-relative dst X coordinate */
int copy; /* accelerate dest-invariant */
int transparent; /* accelerate 0 nop */
Bool copy; /* accelerate dest-invariant */
Bool transparent; /* accelerate 0 nop */
int srcinc; /* source units consumed */
int endNeedsLoad = 0; /* need load for endmask */
#ifndef ICNOPIXADDR
const uint8_t *IcLane;
Bool endNeedsLoad = FALSE; /* need load for endmask */
#ifndef FBNOPIXADDR
const CARD8 *fbLane;
#endif
int startbyte, endbyte;
#ifdef IC_24BIT
#ifdef FB_24BIT
if (dstBpp == 24)
{
IcBltOne24 (src, srcStride, srcX,
fbBltOne24 (src, srcStride, srcX,
dst, dstStride, dstX, dstBpp,
width, height,
fgand, fgxor, bgand, bgxor);
@ -184,32 +184,32 @@ IcBltOne (IcStip *src,
#endif
/*
* Number of destination units in pixman_bits_t == number of stipple pixels
* Number of destination units in FbBits == number of stipple pixels
* used each time
*/
pixelsPerDst = IC_UNIT / dstBpp;
pixelsPerDst = FB_UNIT / dstBpp;
/*
* Number of source stipple patterns in IcStip
* Number of source stipple patterns in FbStip
*/
unitsPerSrc = IC_STIP_UNIT / pixelsPerDst;
unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
copy = 0;
transparent = 0;
copy = FALSE;
transparent = FALSE;
if (bgand == 0 && fgand == 0)
copy = 1;
else if (bgand == IC_ALLONES && bgxor == 0)
transparent = 1;
copy = TRUE;
else if (bgand == FB_ALLONES && bgxor == 0)
transparent = TRUE;
/*
* Adjust source and dest to nearest pixman_bits_t boundary
* Adjust source and dest to nearest FbBits boundary
*/
src += srcX >> IC_STIP_SHIFT;
dst += dstX >> IC_SHIFT;
srcX &= IC_STIP_MASK;
dstX &= IC_MASK;
src += srcX >> FB_STIP_SHIFT;
dst += dstX >> FB_SHIFT;
srcX &= FB_STIP_MASK;
dstX &= FB_MASK;
IcMaskBitsBytes(dstX, width, copy,
FbMaskBitsBytes(dstX, width, copy,
startmask, startbyte, nmiddle, endmask, endbyte);
/*
@ -223,23 +223,23 @@ IcBltOne (IcStip *src,
if (srcX >= dstS)
{
leftShift = srcX - dstS;
rightShift = IC_STIP_UNIT - leftShift;
rightShift = FB_STIP_UNIT - leftShift;
}
else
{
rightShift = dstS - srcX;
leftShift = IC_STIP_UNIT - rightShift;
leftShift = FB_STIP_UNIT - rightShift;
}
/*
* Get pointer to stipple mask array for this depth
*/
icbits = 0; /* unused */
fbBits = 0; /* unused */
if (pixelsPerDst <= 8)
icbits = IcStippleTable(pixelsPerDst);
#ifndef ICNOPIXADDR
IcLane = 0;
fbBits = fbStippleTable(pixelsPerDst);
#ifndef FBNOPIXADDR
fbLane = 0;
if (transparent && fgand == 0 && dstBpp >= 8)
IcLane = IcLaneTable(dstBpp);
fbLane = fbLaneTable(dstBpp);
#endif
/*
@ -294,26 +294,26 @@ IcBltOne (IcStip *src,
*/
if (startmask)
{
#if IC_UNIT > 32
#if FB_UNIT > 32
if (pixelsPerDst == 16)
mask = IcStipple16Bits(IcLeftStipBits(bits,16));
mask = FbStipple16Bits(FbLeftStipBits(bits,16));
else
#endif
mask = icbits[IcLeftStipBits(bits,pixelsPerDst)];
#ifndef ICNOPIXADDR
if (IcLane)
mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
#ifndef FBNOPIXADDR
if (fbLane)
{
IcTransparentSpan (dst, mask & startmask, fgxor, 1);
fbTransparentSpan (dst, mask & startmask, fgxor, 1);
}
else
#endif
{
if (mask || !transparent)
IcDoLeftMaskByteStippleRRop (dst, mask,
FbDoLeftMaskByteStippleRRop (dst, mask,
fgand, fgxor, bgand, bgxor,
startbyte, startmask);
}
bits = IcStipLeft (bits, pixelsPerDst);
bits = FbStipLeft (bits, pixelsPerDst);
dst++;
n--;
w--;
@ -328,28 +328,28 @@ IcBltOne (IcStip *src,
{
while (n--)
{
#if IC_UNIT > 32
#if FB_UNIT > 32
if (pixelsPerDst == 16)
mask = IcStipple16Bits(IcLeftStipBits(bits,16));
mask = FbStipple16Bits(FbLeftStipBits(bits,16));
else
#endif
mask = icbits[IcLeftStipBits(bits,pixelsPerDst)];
*dst = IcOpaqueStipple (mask, fgxor, bgxor);
mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
*dst = FbOpaqueStipple (mask, fgxor, bgxor);
dst++;
bits = IcStipLeft(bits, pixelsPerDst);
bits = FbStipLeft(bits, pixelsPerDst);
}
}
else
{
#ifndef ICNOPIXADDR
if (IcLane)
#ifndef FBNOPIXADDR
if (fbLane)
{
while (bits && n)
{
switch (IcLane[IcLeftStipBits(bits,pixelsPerDst)]) {
LaneCases((uint8_t *) dst);
switch (fbLane[FbLeftStipBits(bits,pixelsPerDst)]) {
LaneCases((CARD8 *) dst);
}
bits = IcStipLeft(bits,pixelsPerDst);
bits = FbStipLeft(bits,pixelsPerDst);
dst++;
n--;
}
@ -360,15 +360,15 @@ IcBltOne (IcStip *src,
{
while (n--)
{
left = IcLeftStipBits(bits,pixelsPerDst);
left = FbLeftStipBits(bits,pixelsPerDst);
if (left || !transparent)
{
mask = icbits[left];
*dst = IcStippleRRop (*dst, mask,
mask = fbBits[left];
*dst = FbStippleRRop (*dst, mask,
fgand, fgxor, bgand, bgxor);
}
dst++;
bits = IcStipLeft(bits, pixelsPerDst);
bits = FbStipLeft(bits, pixelsPerDst);
}
}
}
@ -392,22 +392,22 @@ IcBltOne (IcStip *src,
{
LoadBits;
}
#if IC_UNIT > 32
#if FB_UNIT > 32
if (pixelsPerDst == 16)
mask = IcStipple16Bits(IcLeftStipBits(bits,16));
mask = FbStipple16Bits(FbLeftStipBits(bits,16));
else
#endif
mask = icbits[IcLeftStipBits(bits,pixelsPerDst)];
#ifndef ICNOPIXADDR
if (IcLane)
mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
#ifndef FBNOPIXADDR
if (fbLane)
{
IcTransparentSpan (dst, mask & endmask, fgxor, 1);
fbTransparentSpan (dst, mask & endmask, fgxor, 1);
}
else
#endif
{
if (mask || !transparent)
IcDoRightMaskByteStippleRRop (dst, mask,
FbDoRightMaskByteStippleRRop (dst, mask,
fgand, fgxor, bgand, bgxor,
endbyte, endmask);
}
@ -417,7 +417,7 @@ IcBltOne (IcStip *src,
}
}
#ifdef IC_24BIT
#ifdef FB_24BIT
/*
* Crufty macros to initialize the mask array, most of this
@ -432,9 +432,9 @@ IcBltOne (IcStip *src,
#define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0)
#define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \
Mask24Pos(x,r) >= IC_UNIT ? 0 : Mask24Pos(x,r))
Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r))
#define Mask24(x,r) (Mask24Pos(x,r) < IC_UNIT ? \
#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \
(Mask24Pos(x,r) < 0 ? \
0xffffff >> Mask24Neg (x,r) : \
0xffffff << Mask24Check(x,r)) : 0)
@ -442,20 +442,20 @@ IcBltOne (IcStip *src,
#define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r))
/*
* Untested for MSBFirst or IC_UNIT == 32
* Untested for MSBFirst or FB_UNIT == 32
*/
#if IC_UNIT == 64
#if FB_UNIT == 64
#define C4_24(b,r) \
(SelMask24(b,0,r) | \
SelMask24(b,1,r) | \
SelMask24(b,2,r) | \
SelMask24(b,3,r))
#define IcStip24New(rot) (2 + (rot != 0))
#define IcStip24Len 4
#define FbStip24New(rot) (2 + (rot != 0))
#define FbStip24Len 4
static const pixman_bits_t icStipple24Bits[3][1 << IcStip24Len] = {
static const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
/* rotate 0 */
{
C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0),
@ -481,19 +481,19 @@ static const pixman_bits_t icStipple24Bits[3][1 << IcStip24Len] = {
#endif
#if IC_UNIT == 32
#if FB_UNIT == 32
#define C2_24(b,r) \
(SelMask24(b,0,r) | \
SelMask24(b,1,r))
#define IcStip24Len 2
#define FbStip24Len 2
#if BITMAP_BIT_ORDER == MSBFirst
#define IcStip24New(rot) (1 + (rot == 0))
#define FbStip24New(rot) (1 + (rot == 0))
#else
#define IcStip24New(rot) (1 + (rot == 8))
#define FbStip24New(rot) (1 + (rot == 8))
#endif
static const pixman_bits_t icStipple24Bits[3][1 << IcStip24Len] = {
static const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
/* rotate 0 */
{
C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0),
@ -511,51 +511,51 @@ static const pixman_bits_t icStipple24Bits[3][1 << IcStip24Len] = {
#if BITMAP_BIT_ORDER == LSBFirst
#define IcMergeStip24Bits(left, right, new) \
(IcStipLeft (left, new) | IcStipRight ((right), (IcStip24Len - (new))))
#define FbMergeStip24Bits(left, right, new) \
(FbStipLeft (left, new) | FbStipRight ((right), (FbStip24Len - (new))))
#define IcMergePartStip24Bits(left, right, llen, rlen) \
(left | IcStipRight(right, llen))
#define FbMergePartStip24Bits(left, right, llen, rlen) \
(left | FbStipRight(right, llen))
#else
#define IcMergeStip24Bits(left, right, new) \
((IcStipLeft (left, new) & ((1 << IcStip24Len) - 1)) | right)
#define FbMergeStip24Bits(left, right, new) \
((FbStipLeft (left, new) & ((1 << FbStip24Len) - 1)) | right)
#define IcMergePartStip24Bits(left, right, llen, rlen) \
(IcStipLeft(left, rlen) | right)
#define FbMergePartStip24Bits(left, right, llen, rlen) \
(FbStipLeft(left, rlen) | right)
#endif
#define IcFirstStipBits(len,stip) {\
#define fbFirstStipBits(len,stip) {\
int __len = (len); \
if (len <= remain) { \
stip = IcLeftStipBits(bits, len); \
stip = FbLeftStipBits(bits, len); \
} else { \
stip = IcLeftStipBits(bits, remain); \
stip = FbLeftStipBits(bits, remain); \
bits = *src++; \
__len = (len) - remain; \
stip = IcMergePartStip24Bits(stip, IcLeftStipBits(bits, __len), \
stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
remain, __len); \
remain = IC_STIP_UNIT; \
remain = FB_STIP_UNIT; \
} \
bits = IcStipLeft (bits, __len); \
bits = FbStipLeft (bits, __len); \
remain -= __len; \
}
#define IcInitStipBits(offset,len,stip) {\
bits = IcStipLeft (*src++,offset); \
remain = IC_STIP_UNIT - offset; \
IcFirstStipBits(len,stip); \
stip = IcMergeStip24Bits (0, stip, len); \
#define fbInitStipBits(offset,len,stip) {\
bits = FbStipLeft (*src++,offset); \
remain = FB_STIP_UNIT - offset; \
fbFirstStipBits(len,stip); \
stip = FbMergeStip24Bits (0, stip, len); \
}
#define IcNextStipBits(rot,stip) {\
int __new = IcStip24New(rot); \
IcStip __right; \
IcFirstStipBits(__new, __right); \
stip = IcMergeStip24Bits (stip, __right, __new); \
rot = IcNext24Rot (rot); \
#define fbNextStipBits(rot,stip) {\
int __new = FbStip24New(rot); \
FbStip __right; \
fbFirstStipBits(__new, __right); \
stip = FbMergeStip24Bits (stip, __right, __new); \
rot = FbNext24Rot (rot); \
}
/*
@ -568,42 +568,42 @@ static const pixman_bits_t icStipple24Bits[3][1 << IcStip24Len] = {
* and text
*/
void
IcBltOne24 (IcStip *srcLine,
IcStride srcStride, /* IcStip units per scanline */
fbBltOne24 (FbStip *srcLine,
FbStride srcStride, /* FbStip units per scanline */
int srcX, /* bit position of source */
pixman_bits_t *dst,
IcStride dstStride, /* pixman_bits_t units per scanline */
FbBits *dst,
FbStride dstStride, /* FbBits units per scanline */
int dstX, /* bit position of dest */
int dstBpp, /* bits per destination unit */
int width, /* width in bits of destination */
int height, /* height in scanlines */
pixman_bits_t fgand, /* rrop values */
pixman_bits_t fgxor,
pixman_bits_t bgand,
pixman_bits_t bgxor)
FbBits fgand, /* rrop values */
FbBits fgxor,
FbBits bgand,
FbBits bgxor)
{
IcStip *src;
pixman_bits_t leftMask, rightMask, mask;
FbStip *src;
FbBits leftMask, rightMask, mask;
int nlMiddle, nl;
IcStip stip, bits;
FbStip stip, bits;
int remain;
int dstS;
int firstlen;
int rot0, rot;
int nDst;
srcLine += srcX >> IC_STIP_SHIFT;
dst += dstX >> IC_SHIFT;
srcX &= IC_STIP_MASK;
dstX &= IC_MASK;
rot0 = IcFirst24Rot (dstX);
srcLine += srcX >> FB_STIP_SHIFT;
dst += dstX >> FB_SHIFT;
srcX &= FB_STIP_MASK;
dstX &= FB_MASK;
rot0 = FbFirst24Rot (dstX);
IcMaskBits (dstX, width, leftMask, nlMiddle, rightMask);
FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask);
dstS = (dstX + 23) / 24;
firstlen = IcStip24Len - dstS;
firstlen = FbStip24Len - dstS;
nDst = nlMiddle;
if (leftMask)
@ -618,33 +618,33 @@ IcBltOne24 (IcStip *srcLine,
rot = rot0;
src = srcLine;
srcLine += srcStride;
IcInitStipBits (srcX,firstlen, stip);
fbInitStipBits (srcX,firstlen, stip);
if (leftMask)
{
mask = icStipple24Bits[rot >> 3][stip];
*dst = (*dst & ~leftMask) | (IcOpaqueStipple (mask,
IcRot24(fgxor, rot),
IcRot24(bgxor, rot))
mask = fbStipple24Bits[rot >> 3][stip];
*dst = (*dst & ~leftMask) | (FbOpaqueStipple (mask,
FbRot24(fgxor, rot),
FbRot24(bgxor, rot))
& leftMask);
dst++;
IcNextStipBits(rot,stip);
fbNextStipBits(rot,stip);
}
nl = nlMiddle;
while (nl--)
{
mask = icStipple24Bits[rot>>3][stip];
*dst = IcOpaqueStipple (mask,
IcRot24(fgxor, rot),
IcRot24(bgxor, rot));
mask = fbStipple24Bits[rot>>3][stip];
*dst = FbOpaqueStipple (mask,
FbRot24(fgxor, rot),
FbRot24(bgxor, rot));
dst++;
IcNextStipBits(rot,stip);
fbNextStipBits(rot,stip);
}
if (rightMask)
{
mask = icStipple24Bits[rot >> 3][stip];
*dst = (*dst & ~rightMask) | (IcOpaqueStipple (mask,
IcRot24(fgxor, rot),
IcRot24(bgxor, rot))
mask = fbStipple24Bits[rot >> 3][stip];
*dst = (*dst & ~rightMask) | (FbOpaqueStipple (mask,
FbRot24(fgxor, rot),
FbRot24(bgxor, rot))
& rightMask);
}
dst += dstStride;
@ -652,41 +652,41 @@ IcBltOne24 (IcStip *srcLine,
}
}
/* transparent copy */
else if (bgand == IC_ALLONES && bgxor == 0 && fgand == 0)
else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0)
{
while (height--)
{
rot = rot0;
src = srcLine;
srcLine += srcStride;
IcInitStipBits (srcX, firstlen, stip);
fbInitStipBits (srcX, firstlen, stip);
if (leftMask)
{
if (stip)
{
mask = icStipple24Bits[rot >> 3][stip] & leftMask;
*dst = (*dst & ~mask) | (IcRot24(fgxor, rot) & mask);
mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
*dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
}
dst++;
IcNextStipBits (rot, stip);
fbNextStipBits (rot, stip);
}
nl = nlMiddle;
while (nl--)
{
if (stip)
{
mask = icStipple24Bits[rot>>3][stip];
*dst = (*dst & ~mask) | (IcRot24(fgxor,rot) & mask);
mask = fbStipple24Bits[rot>>3][stip];
*dst = (*dst & ~mask) | (FbRot24(fgxor,rot) & mask);
}
dst++;
IcNextStipBits (rot, stip);
fbNextStipBits (rot, stip);
}
if (rightMask)
{
if (stip)
{
mask = icStipple24Bits[rot >> 3][stip] & rightMask;
*dst = (*dst & ~mask) | (IcRot24(fgxor, rot) & mask);
mask = fbStipple24Bits[rot >> 3][stip] & rightMask;
*dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
}
}
dst += dstStride;
@ -699,39 +699,39 @@ IcBltOne24 (IcStip *srcLine,
rot = rot0;
src = srcLine;
srcLine += srcStride;
IcInitStipBits (srcX, firstlen, stip);
fbInitStipBits (srcX, firstlen, stip);
if (leftMask)
{
mask = icStipple24Bits[rot >> 3][stip];
*dst = IcStippleRRopMask (*dst, mask,
IcRot24(fgand, rot),
IcRot24(fgxor, rot),
IcRot24(bgand, rot),
IcRot24(bgxor, rot),
mask = fbStipple24Bits[rot >> 3][stip];
*dst = FbStippleRRopMask (*dst, mask,
FbRot24(fgand, rot),
FbRot24(fgxor, rot),
FbRot24(bgand, rot),
FbRot24(bgxor, rot),
leftMask);
dst++;
IcNextStipBits(rot,stip);
fbNextStipBits(rot,stip);
}
nl = nlMiddle;
while (nl--)
{
mask = icStipple24Bits[rot >> 3][stip];
*dst = IcStippleRRop (*dst, mask,
IcRot24(fgand, rot),
IcRot24(fgxor, rot),
IcRot24(bgand, rot),
IcRot24(bgxor, rot));
mask = fbStipple24Bits[rot >> 3][stip];
*dst = FbStippleRRop (*dst, mask,
FbRot24(fgand, rot),
FbRot24(fgxor, rot),
FbRot24(bgand, rot),
FbRot24(bgxor, rot));
dst++;
IcNextStipBits(rot,stip);
fbNextStipBits(rot,stip);
}
if (rightMask)
{
mask = icStipple24Bits[rot >> 3][stip];
*dst = IcStippleRRopMask (*dst, mask,
IcRot24(fgand, rot),
IcRot24(fgxor, rot),
IcRot24(bgand, rot),
IcRot24(bgxor, rot),
mask = fbStipple24Bits[rot >> 3][stip];
*dst = FbStippleRRopMask (*dst, mask,
FbRot24(fgand, rot),
FbRot24(fgxor, rot),
FbRot24(bgand, rot),
FbRot24(bgxor, rot),
rightMask);
}
dst += dstStride;

Просмотреть файл

@ -26,7 +26,7 @@
#ifdef ICINT_NEED_IC_ONES
/* Fall back on HACKMEM 169. */
int
_IcOnes (unsigned long mask)
_FbOnes (unsigned long mask)
{
register unsigned long y;
@ -43,10 +43,10 @@ pixman_color_to_pixel (const pixman_format_t *format,
{
uint32_t r, g, b, a;
r = color->red >> (16 - _IcOnes (format->redMask));
g = color->green >> (16 - _IcOnes (format->greenMask));
b = color->blue >> (16 - _IcOnes (format->blueMask));
a = color->alpha >> (16 - _IcOnes (format->alphaMask));
r = color->red >> (16 - _FbOnes (format->redMask));
g = color->green >> (16 - _FbOnes (format->greenMask));
b = color->blue >> (16 - _FbOnes (format->blueMask));
a = color->alpha >> (16 - _FbOnes (format->alphaMask));
r = r << format->red;
g = g << format->green;
b = b << format->blue;
@ -56,7 +56,7 @@ pixman_color_to_pixel (const pixman_format_t *format,
slim_hidden_def(pixman_color_to_pixel);
static uint16_t
IcFillColor (uint32_t pixel, int bits)
FbFillColor (uint32_t pixel, int bits)
{
while (bits < 16)
{
@ -77,8 +77,8 @@ pixman_pixel_to_color (const pixman_format_t *format,
g = (pixel >> format->green) & format->greenMask;
b = (pixel >> format->blue) & format->blueMask;
a = (pixel >> format->alpha) & format->alphaMask;
color->red = IcFillColor (r, _IcOnes (format->redMask));
color->green = IcFillColor (r, _IcOnes (format->greenMask));
color->blue = IcFillColor (r, _IcOnes (format->blueMask));
color->alpha = IcFillColor (r, _IcOnes (format->alphaMask));
color->red = FbFillColor (r, _FbOnes (format->redMask));
color->green = FbFillColor (r, _FbOnes (format->greenMask));
color->blue = FbFillColor (r, _FbOnes (format->blueMask));
color->alpha = FbFillColor (r, _FbOnes (format->alphaMask));
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -76,10 +76,10 @@ pixman_format_create_masks (int bpp,
type = PICT_TYPE_ABGR;
format_code = PICT_FORMAT (bpp, type,
_IcOnes (alpha_mask),
_IcOnes (red_mask),
_IcOnes (green_mask),
_IcOnes (blue_mask));
_FbOnes (alpha_mask),
_FbOnes (red_mask),
_FbOnes (green_mask),
_FbOnes (blue_mask));
format = malloc (sizeof (pixman_format_t));
if (format == NULL)
@ -148,7 +148,7 @@ pixman_format_init (pixman_format_t *format, int format_code)
break;
}
format->depth = _IcOnes ((format->alphaMask << format->alpha) |
format->depth = _FbOnes ((format->alphaMask << format->alpha) |
(format->redMask << format->red) |
(format->blueMask << format->blue) |
(format->greenMask << format->green));

Просмотреть файл

@ -21,7 +21,7 @@
* Author: Keith Packard, SuSE, Inc.
*/
#include "icint.h"
#include "pixman-xserver-compat.h"
pixman_image_t *
pixman_image_create (pixman_format_t *format,
@ -29,15 +29,15 @@ pixman_image_create (pixman_format_t *format,
int height)
{
pixman_image_t *image;
IcPixels *pixels;
FbPixels *pixels;
pixels = IcPixelsCreate (width, height, format->depth);
pixels = FbPixelsCreate (width, height, format->depth);
if (pixels == NULL)
return NULL;
image = pixman_image_createForPixels (pixels, format);
if (image == NULL) {
IcPixelsDestroy (pixels);
FbPixelsDestroy (pixels);
return NULL;
}
@ -48,18 +48,18 @@ pixman_image_create (pixman_format_t *format,
slim_hidden_def(pixman_image_create);
pixman_image_t *
pixman_image_create_for_data (pixman_bits_t *data, pixman_format_t *format, int width, int height, int bpp, int stride)
pixman_image_create_for_data (FbBits *data, pixman_format_t *format, int width, int height, int bpp, int stride)
{
pixman_image_t *image;
IcPixels *pixels;
FbPixels *pixels;
pixels = IcPixelsCreateForData (data, width, height, format->depth, bpp, stride);
pixels = FbPixelsCreateForData (data, width, height, format->depth, bpp, stride);
if (pixels == NULL)
return NULL;
image = pixman_image_createForPixels (pixels, format);
if (image == NULL) {
IcPixelsDestroy (pixels);
FbPixelsDestroy (pixels);
return NULL;
}
@ -69,7 +69,7 @@ pixman_image_create_for_data (pixman_bits_t *data, pixman_format_t *format, int
}
pixman_image_t *
pixman_image_createForPixels (IcPixels *pixels,
pixman_image_createForPixels (FbPixels *pixels,
pixman_format_t *format)
{
pixman_image_t *image;
@ -110,10 +110,15 @@ pixman_image_init (pixman_image_t *image)
image->subWindowMode = ClipByChildren;
image->polyEdge = PolyEdgeSharp;
image->polyMode = PolyModePrecise;
/* XXX: In the server this was 0. Why? */
image->freeCompClip = 1;
/*
* In the server this was 0 because the composite clip list
* can be referenced from a window (and often is)
*/
image->freeCompClip = 0;
image->freeSourceClip = 0;
image->clientClipType = CT_NONE;
image->componentAlpha = 0;
image->compositeClipSource = 0;
image->alphaMap = 0;
image->alphaOrigin.x = 0;
@ -133,7 +138,13 @@ pixman_image_init (pixman_image_t *image)
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;
image->transform = NULL;
image->filter = PIXMAN_FILTER_NEAREST;
@ -146,7 +157,7 @@ pixman_image_init (pixman_image_t *image)
void
pixman_image_set_component_alpha (pixman_image_t *image,
int component_alpha)
int component_alpha)
{
if (image)
image->componentAlpha = component_alpha;
@ -234,7 +245,7 @@ pixman_image_get_format (pixman_image_t *image)
return &image->image_format;
}
pixman_bits_t *
FbBits *
pixman_image_get_data (pixman_image_t *image)
{
return image->pixels->data;
@ -243,13 +254,20 @@ pixman_image_get_data (pixman_image_t *image)
void
pixman_image_destroy (pixman_image_t *image)
{
pixman_image_destroyClip (image);
if (image->freeCompClip) {
pixman_region_destroy (image->pCompositeClip);
image->pCompositeClip = NULL;
}
if (image->freeSourceClip) {
pixman_region_destroy (image->pSourceClip);
image->pSourceClip = NULL;
}
if (image->owns_pixels) {
IcPixelsDestroy (image->pixels);
FbPixelsDestroy (image->pixels);
image->pixels = NULL;
}
@ -281,7 +299,7 @@ pixman_image_destroyClip (pixman_image_t *image)
int
pixman_image_set_clip_region (pixman_image_t *image,
pixman_region16_t *region)
pixman_region16_t *region)
{
pixman_image_destroyClip (image);
if (region) {
@ -290,9 +308,12 @@ pixman_image_set_clip_region (pixman_image_t *image,
image->clientClipType = CT_REGION;
}
if (image->freeCompClip)
pixman_region_destroy (image->pCompositeClip);
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 (region) {
pixman_region_translate (image->pCompositeClip,
- image->clipOrigin.x,
@ -312,7 +333,7 @@ pixman_image_set_clip_region (pixman_image_t *image,
#define BOUND(v) (int16_t) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
static __inline int
IcClipImageReg (pixman_region16_t *region,
FbClipImageReg (pixman_region16_t *region,
pixman_region16_t *clip,
int dx,
int dy)
@ -348,7 +369,7 @@ IcClipImageReg (pixman_region16_t *region,
}
static __inline int
IcClipImageSrc (pixman_region16_t *region,
FbClipImageSrc (pixman_region16_t *region,
pixman_image_t *image,
int dx,
int dy)
@ -358,7 +379,9 @@ IcClipImageSrc (pixman_region16_t *region,
return 1;
if (image->repeat)
{
if (image->clientClipType != CT_NONE)
/* XXX no source clipping */
if (image->compositeClipSource &&
image->clientClipType != CT_NONE)
{
pixman_region_translate (region,
dx - image->clipOrigin.x,
@ -372,8 +395,14 @@ IcClipImageSrc (pixman_region16_t *region,
}
else
{
return IcClipImageReg (region,
image->pCompositeClip,
pixman_region16_t *clip;
if (image->compositeClipSource)
clip = image->pCompositeClip;
else
clip = image->pSourceClip;
return FbClipImageReg (region,
clip,
dx,
dy);
}
@ -567,7 +596,7 @@ SetPictureClipRects (PicturePtr pPicture,
*/
int
IcComputeCompositeRegion (pixman_region16_t *region,
FbComputeCompositeRegion (pixman_region16_t *region,
pixman_image_t *iSrc,
pixman_image_t *iMask,
pixman_image_t *iDst,
@ -602,14 +631,14 @@ IcComputeCompositeRegion (pixman_region16_t *region,
return 1;
}
/* clip against src */
if (!IcClipImageSrc (region, iSrc, xDst - xSrc, yDst - ySrc))
if (!FbClipImageSrc (region, iSrc, xDst - xSrc, yDst - ySrc))
{
pixman_region_destroy (region);
return 0;
}
if (iSrc->alphaMap)
{
if (!IcClipImageSrc (region, iSrc->alphaMap,
if (!FbClipImageSrc (region, iSrc->alphaMap,
xDst - (xSrc + iSrc->alphaOrigin.x),
yDst - (ySrc + iSrc->alphaOrigin.y)))
{
@ -620,14 +649,14 @@ IcComputeCompositeRegion (pixman_region16_t *region,
/* clip against mask */
if (iMask)
{
if (!IcClipImageSrc (region, iMask, xDst - xMask, yDst - yMask))
if (!FbClipImageSrc (region, iMask, xDst - xMask, yDst - yMask))
{
pixman_region_destroy (region);
return 0;
}
if (iMask->alphaMap)
{
if (!IcClipImageSrc (region, iMask->alphaMap,
if (!FbClipImageSrc (region, iMask->alphaMap,
xDst - (xMask + iMask->alphaOrigin.x),
yDst - (yMask + iMask->alphaOrigin.y)))
{
@ -636,14 +665,14 @@ IcComputeCompositeRegion (pixman_region16_t *region,
}
}
}
if (!IcClipImageReg (region, iDst->pCompositeClip, 0, 0))
if (!FbClipImageReg (region, iDst->pCompositeClip, 0, 0))
{
pixman_region_destroy (region);
return 0;
}
if (iDst->alphaMap)
{
if (!IcClipImageReg (region, iDst->alphaMap->pCompositeClip,
if (!FbClipImageReg (region, iDst->alphaMap->pCompositeClip,
-iDst->alphaOrigin.x,
-iDst->alphaOrigin.y))
{

Просмотреть файл

@ -33,38 +33,6 @@
#include "resource.h"
*/
#define IcIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
#define IcIntDiv(a,b) (((uint16_t) (a) * 255) / (b))
#define IcGet8(v,i) ((uint16_t) (uint8_t) ((v) >> i))
/*
* There are two ways of handling alpha -- either as a single unified value or
* a separate value for each component, hence each macro must have two
* versions. The unified alpha version has a 'U' at the end of the name,
* the component version has a 'C'. Similarly, functions which deal with
* this difference will have two versions using the same convention.
*/
#define IcOverU(x,y,i,a,t) ((t) = IcIntMult(IcGet8(y,i),(a),(t)) + IcGet8(x,i),\
(uint32_t) ((uint8_t) ((t) | (0 - ((t) >> 8)))) << (i))
#define IcOverC(x,y,i,a,t) ((t) = IcIntMult(IcGet8(y,i),IcGet8(a,i),(t)) + IcGet8(x,i),\
(uint32_t) ((uint8_t) ((t) | (0 - ((t) >> 8)))) << (i))
#define IcInU(x,i,a,t) ((uint32_t) IcIntMult(IcGet8(x,i),(a),(t)) << (i))
#define IcInC(x,i,a,t) ((uint32_t) IcIntMult(IcGet8(x,i),IcGet8(a,i),(t)) << (i))
#define IcGen(x,y,i,ax,ay,t,u,v) ((t) = (IcIntMult(IcGet8(y,i),ay,(u)) + \
IcIntMult(IcGet8(x,i),ax,(v))),\
(uint32_t) ((uint8_t) ((t) | \
(0 - ((t) >> 8)))) << (i))
#define IcAdd(x,y,i,t) ((t) = IcGet8(x,i) + IcGet8(y,i), \
(uint32_t) ((uint8_t) ((t) | (0 - ((t) >> 8)))) << (i))
/*
typedef struct _IndexFormat {
VisualPtr pVisual;
@ -87,7 +55,7 @@ typedef struct pixman_format {
*/
struct pixman_image {
IcPixels *pixels;
FbPixels *pixels;
pixman_format_t image_format;
int format_code;
int refcnt;
@ -97,16 +65,17 @@ struct pixman_image {
unsigned int subWindowMode : 1;
unsigned int polyEdge : 1;
unsigned int polyMode : 1;
/* XXX: Do we need this field */
unsigned int freeCompClip : 1;
unsigned int freeSourceClip : 1;
unsigned int clientClipType : 2;
unsigned int componentAlpha : 1;
unsigned int unused : 23;
unsigned int compositeClipSource : 1;
unsigned int unused : 21;
struct pixman_image *alphaMap;
IcPoint alphaOrigin;
FbPoint alphaOrigin;
IcPoint clipOrigin;
FbPoint clipOrigin;
void *clientClip;
unsigned long dither;
@ -115,6 +84,7 @@ struct pixman_image {
unsigned long serialNumber;
pixman_region16_t *pCompositeClip;
pixman_region16_t *pSourceClip;
pixman_transform_t *transform;
@ -133,28 +103,27 @@ struct pixman_image {
#define IC_MAX_INDEXED 256 /* XXX depth must be <= 8 */
#if IC_MAX_INDEXED <= 256
typedef uint8_t IcIndexType;
typedef uint8_t FbIndexType;
#endif
/* XXX: We're not supporting indexed operations, right?
typedef struct _IcIndexed {
/* XXX: We're not supporting indexed operations, right? */
typedef struct _FbIndexed {
int color;
uint32_t rgba[IC_MAX_INDEXED];
IcIndexType ent[32768];
} IcIndexedRec, *IcIndexedPtr;
*/
FbIndexType ent[32768];
} FbIndexedRec, *FbIndexedPtr;
#define IcCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
#define FbCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
(((s) >> 6) & 0x03e0) | \
(((s) >> 9) & 0x7c00))
#define IcIndexToEnt15(icf,rgb15) ((icf)->ent[rgb15])
#define IcIndexToEnt24(icf,rgb24) IcIndexToEnt15(icf,IcCvtR8G8B8to15(rgb24))
#define FbIndexToEnt15(icf,rgb15) ((icf)->ent[rgb15])
#define FbIndexToEnt24(icf,rgb24) FbIndexToEnt15(icf,FbCvtR8G8B8to15(rgb24))
#define IcIndexToEntY24(icf,rgb24) ((icf)->ent[CvtR8G8B8toY15(rgb24)])
#define FbIndexToEntY24(icf,rgb24) ((icf)->ent[CvtR8G8B8toY15(rgb24)])
/*
pixman_private int
IcCreatePicture (PicturePtr pPicture);
FbCreatePicture (PicturePtr pPicture);
*/
pixman_private void
@ -165,14 +134,14 @@ pixman_image_destroyClip (pixman_image_t *image);
/*
pixman_private void
IcValidatePicture (PicturePtr pPicture,
FbValidatePicture (PicturePtr pPicture,
Mask mask);
*/
/* XXX: What should this be?
pixman_private int
IcClipPicture (pixman_region16_t *region,
FbClipPicture (pixman_region16_t *region,
pixman_image_t *image,
int16_t xReg,
int16_t yReg,
@ -181,7 +150,7 @@ IcClipPicture (pixman_region16_t *region,
*/
pixman_private int
IcComputeCompositeRegion (pixman_region16_t *region,
FbComputeCompositeRegion (pixman_region16_t *region,
pixman_image_t *iSrc,
pixman_image_t *iMask,
pixman_image_t *iDst,
@ -199,12 +168,12 @@ miIsSolidAlpha (pixman_image_t *src);
/*
pixman_private int
IcPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
FbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
*/
/*
pixman_private void
IcGlyphs (pixman_operator_t op,
FbGlyphs (pixman_operator_t op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
@ -225,7 +194,7 @@ pixman_compositeRects (pixman_operator_t op,
*/
pixman_private pixman_image_t *
IcCreateAlphaPicture (pixman_image_t *dst,
FbCreateAlphaPicture (pixman_image_t *dst,
pixman_format_t *format,
uint16_t width,
uint16_t height);
@ -243,15 +212,15 @@ typedef void (*CompositeFunc) (pixman_operator_t op,
uint16_t width,
uint16_t height);
typedef struct _pixman_compositeOperand pixman_compositeOperand;
typedef struct _FbCompositeOperand FbCompositeOperand;
typedef uint32_t (*pixman_compositeFetch)(pixman_compositeOperand *op);
typedef void (*pixman_compositeStore) (pixman_compositeOperand *op, uint32_t value);
typedef uint32_t (*pixman_compositeFetch)(FbCompositeOperand *op);
typedef void (*pixman_compositeStore) (FbCompositeOperand *op, uint32_t value);
typedef void (*pixman_compositeStep) (pixman_compositeOperand *op);
typedef void (*pixman_compositeSet) (pixman_compositeOperand *op, int x, int y);
typedef void (*pixman_compositeStep) (FbCompositeOperand *op);
typedef void (*pixman_compositeSet) (FbCompositeOperand *op, int x, int y);
struct _pixman_compositeOperand {
struct _FbCompositeOperand {
union {
struct {
pixman_bits_t *top_line;
@ -260,7 +229,7 @@ struct _pixman_compositeOperand {
int start_offset;
pixman_bits_t *line;
uint32_t offset;
IcStride stride;
FbStride stride;
int bpp;
} drawable;
struct {
@ -287,32 +256,33 @@ struct _pixman_compositeOperand {
pixman_compositeStep down;
pixman_compositeSet set;
/* XXX: We're not supporting indexed operations, right?
IcIndexedPtr indexed;
FbIndexedPtr indexed;
*/
pixman_region16_t *clip;
pixman_region16_t *dst_clip;
pixman_region16_t *src_clip;
};
typedef void (*IcCombineFunc) (pixman_compositeOperand *src,
pixman_compositeOperand *msk,
pixman_compositeOperand *dst);
typedef void (*FbCombineFunc) (FbCompositeOperand *src,
FbCompositeOperand *msk,
FbCompositeOperand *dst);
typedef struct _IcAccessMap {
typedef struct _FbAccessMap {
uint32_t format_code;
pixman_compositeFetch fetch;
pixman_compositeFetch fetcha;
pixman_compositeStore store;
} IcAccessMap;
} FbAccessMap;
/* iccompose.c */
typedef struct _IcCompSrc {
typedef struct _FbCompSrc {
uint32_t value;
uint32_t alpha;
} IcCompSrc;
} FbCompSrc;
pixman_private int
IcBuildCompositeOperand (pixman_image_t *image,
pixman_compositeOperand op[4],
fbBuildCompositeOperand (pixman_image_t *image,
FbCompositeOperand op[4],
int16_t x,
int16_t y,
int transform,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: icpixels.c,v 1.3 2005/06/04 07:03:28 vladimir%pobox.com Exp $
* $Id: icpixels.c,v 1.8 2006/02/03 04:49:30 vladimir%pobox.com Exp $
*
* Copyright © 1998 Keith Packard
*
@ -22,10 +22,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "icint.h"
#include "pixman-xserver-compat.h"
static void
IcPixelsInit (IcPixels *pixels, pixman_bits_t *buf, int width, int height, int depth, int bpp, int stride);
FbPixelsInit (FbPixels *pixels, pixman_bits_t *buf, int width, int height, int depth, int bpp, int stride);
static unsigned int
pixman_bits_per_pixel (unsigned int depth);
@ -47,10 +47,10 @@ pixman_bits_per_pixel (unsigned int depth)
return 1;
}
IcPixels *
IcPixelsCreate (int width, int height, int depth)
FbPixels *
FbPixelsCreate (int width, int height, int depth)
{
IcPixels *pixels;
FbPixels *pixels;
pixman_bits_t *buf;
unsigned int buf_size;
unsigned int bpp;
@ -59,9 +59,9 @@ IcPixelsCreate (int width, int height, int depth)
unsigned int base;
bpp = pixman_bits_per_pixel (depth);
stride = ((width * bpp + IC_MASK) >> IC_SHIFT) * sizeof (pixman_bits_t);
stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (pixman_bits_t);
buf_size = height * stride;
base = sizeof (IcPixels);
base = sizeof (FbPixels);
adjust = 0;
if (base & 7)
adjust = 8 - (base & 7);
@ -73,27 +73,27 @@ IcPixelsCreate (int width, int height, int depth)
buf = (pixman_bits_t *) ((char *)pixels + base + adjust);
IcPixelsInit (pixels, buf, width, height, depth, bpp, stride);
FbPixelsInit (pixels, buf, width, height, depth, bpp, stride);
return pixels;
}
IcPixels *
IcPixelsCreateForData (pixman_bits_t *data, int width, int height, int depth, int bpp, int stride)
FbPixels *
FbPixelsCreateForData (pixman_bits_t *data, int width, int height, int depth, int bpp, int stride)
{
IcPixels *pixels;
FbPixels *pixels;
pixels = malloc (sizeof (IcPixels));
pixels = malloc (sizeof (FbPixels));
if (pixels == NULL)
return NULL;
IcPixelsInit (pixels, data, width, height, depth, bpp, stride);
FbPixelsInit (pixels, data, width, height, depth, bpp, stride);
return pixels;
}
static void
IcPixelsInit (IcPixels *pixels, pixman_bits_t *buf, int width, int height, int depth, int bpp, int stride)
FbPixelsInit (FbPixels *pixels, pixman_bits_t *buf, int width, int height, int depth, int bpp, int stride)
{
pixels->data = buf;
pixels->width = width;
@ -107,7 +107,7 @@ IcPixelsInit (IcPixels *pixels, pixman_bits_t *buf, int width, int height, int d
}
void
IcPixelsDestroy (IcPixels *pixels)
FbPixelsDestroy (FbPixels *pixels)
{
if(--pixels->refcnt)
return;

Просмотреть файл

@ -30,6 +30,77 @@ typedef void (*FillFunc) (pixman_image_t *dst,
pixman_bits_t *pixel);
static void
pixman_fill_rect_1bpp (pixman_image_t *dst,
int16_t xDst,
int16_t yDst,
uint16_t width,
uint16_t height,
pixman_bits_t *pixel)
{
uint32_t value = *pixel ? 0xffffffff : 0;
char *line;
line = (char *)dst->pixels->data
+ yDst * dst->pixels->stride;
if ((width + xDst - 1) / 32 == xDst / 32) {
uint32_t mask = 0;
int pos = xDst / 32;
int i;
for (i = xDst; i < width; i++)
#if BITMAP_BIT_ORDER == MSBFirst
mask |= 1 << (0x1f - i);
#else
mask |= 1 << i;
#endif
while (height-- > 0) {
uint32_t *cur = (uint32_t *) line;
cur [pos] = (cur [pos] & ~mask) | (value & mask);
line += dst->pixels->stride;
}
} else {
uint32_t smask = 0, emask = 0;
int end = ((xDst + width) / 32);
int i;
if (xDst % 32)
for (i = (xDst % 32); i < 32; i++)
#if BITMAP_BIT_ORDER == MSBFirst
smask |= 1 << (0x1f - i);
#else
smask |= 1 << i;
#endif
if ((width + xDst) % 32)
for (i = 0; i < (width + xDst) % 32; i++)
#if BITMAP_BIT_ORDER == MSBFirst
emask |= 1 << (0x1f - i);
#else
emask |= 1 << i;
#endif
while (height-- > 0) {
uint32_t *cur = (uint32_t *) line;
int start = (xDst / 32);
if (smask) {
cur [start] = (cur [start] & ~smask) | (value & smask);
start++;
}
if (emask)
cur [end] = (cur [end] & ~emask) | (value & emask);
if (end > start)
memset (cur + start, value, (end - start) * 4);
line += dst->pixels->stride;
}
}
}
static void
pixman_fill_rect_8bpp (pixman_image_t *dst,
int16_t xDst,
@ -174,6 +245,8 @@ pixman_color_rects (pixman_image_t *dst,
func = pixman_fill_rect_8bpp;
else if (dst->pixels->bpp == 32)
func = pixman_fill_rect_32bpp;
else if (dst->pixels->bpp == 1)
func = pixman_fill_rect_1bpp;
else
func = pixman_fill_rect_general;
@ -247,13 +320,13 @@ pixman_fill_rectangles (pixman_operator_t op,
else
{
pixman_format_t rgbaFormat;
IcPixels *pixels;
FbPixels *pixels;
pixman_image_t *src;
pixman_bits_t pixel;
pixman_format_init (&rgbaFormat, PICT_a8r8g8b8);
pixels = IcPixelsCreate (1, 1, rgbaFormat.depth);
pixels = FbPixelsCreate (1, 1, rgbaFormat.depth);
if (!pixels)
goto bail1;
@ -286,7 +359,7 @@ pixman_fill_rectangles (pixman_operator_t op,
pixman_image_destroy (src);
bail2:
IcPixelsDestroy (pixels);
FbPixelsDestroy (pixels);
bail1:
;
}

Просмотреть файл

@ -26,112 +26,112 @@
#define _ICROP_H_
typedef struct _mergeRopBits {
pixman_bits_t ca1, cx1, ca2, cx2;
} IcMergeRopRec, *IcMergeRopPtr;
FbBits ca1, cx1, ca2, cx2;
} FbMergeRopRec, *FbMergeRopPtr;
extern const IcMergeRopRec IcMergeRopBits[16] pixman_private;
extern const FbMergeRopRec FbMergeRopBits[16] pixman_private;
#define IcDeclareMergeRop() pixman_bits_t _ca1, _cx1, _ca2, _cx2;
#define IcDeclarePrebuiltMergeRop() pixman_bits_t _cca, _ccx;
#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2;
#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx;
#define IcInitializeMergeRop(alu,pm) {\
const IcMergeRopRec *_bits; \
_bits = &IcMergeRopBits[alu]; \
#define FbInitializeMergeRop(alu,pm) {\
const FbMergeRopRec *_bits; \
_bits = &FbMergeRopBits[alu]; \
_ca1 = _bits->ca1 & pm; \
_cx1 = _bits->cx1 | ~pm; \
_ca2 = _bits->ca2 & pm; \
_cx2 = _bits->cx2 & pm; \
}
#define IcDestInvarientRop(alu,pm) ((pm) == IC_ALLONES && \
#define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \
(((alu) >> 1 & 5) == ((alu) & 5)))
#define IcDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
/* AND has higher precedence than XOR */
#define IcDoMergeRop(src, dst) \
#define FbDoMergeRop(src, dst) \
(((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
#define IcDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2)
#define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2)
#define IcDoMaskMergeRop(src, dst, mask) \
#define FbDoMaskMergeRop(src, dst, mask) \
(((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
#define IcDoLeftMaskByteMergeRop(dst, src, lb, l) { \
pixman_bits_t __xor = ((src) & _ca2) ^ _cx2; \
IcDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \
FbBits __xor = ((src) & _ca2) ^ _cx2; \
FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
}
#define IcDoRightMaskByteMergeRop(dst, src, rb, r) { \
pixman_bits_t __xor = ((src) & _ca2) ^ _cx2; \
IcDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \
FbBits __xor = ((src) & _ca2) ^ _cx2; \
FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
}
#define IcDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
#define IcDoMaskRRop(dst, and, xor, mask) \
#define FbDoMaskRRop(dst, and, xor, mask) \
(((dst) & ((and) | ~(mask))) ^ (xor & mask))
/*
* Take a single bit (0 or 1) and generate a full mask
*/
#define IcFillFromBit(b,t) (~((t) ((b) & 1)-1))
#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1))
#define IcXorT(rop,fg,pm,t) ((((fg) & IcFillFromBit((rop) >> 1,t)) | \
(~(fg) & IcFillFromBit((rop) >> 3,t))) & (pm))
#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
(~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
#define IcAndT(rop,fg,pm,t) ((((fg) & IcFillFromBit (rop ^ (rop>>1),t)) | \
(~(fg) & IcFillFromBit((rop>>2) ^ (rop>>3),t))) | \
#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
(~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
~(pm))
#define IcXor(rop,fg,pm) IcXorT(rop,fg,pm,pixman_bits_t)
#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits)
#define IcAnd(rop,fg,pm) IcAndT(rop,fg,pm,pixman_bits_t)
#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits)
#define IcXorStip(rop,fg,pm) IcXorT(rop,fg,pm,IcStip)
#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip)
#define IcAndStip(rop,fg,pm) IcAndT(rop,fg,pm,IcStip)
#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip)
/*
* Stippling operations;
*/
/* half of table */
extern const pixman_bits_t icStipple16Bits[256] pixman_private;
#define IcStipple16Bits(b) \
(icStipple16Bits[(b)&0xff] | icStipple16Bits[(b) >> 8] << IC_HALFUNIT)
extern const pixman_bits_t fbStipple16Bits[256] pixman_private;
#define FbStipple16Bits(b) \
(fbStipple16Bits[(b)&0xff] | fbStipple16Bits[(b) >> 8] << FB_HALFUNIT)
pixman_private const pixman_bits_t *
IcStippleTable(int bits);
fbStippleTable(int bits);
#define IcStippleRRop(dst, b, fa, fx, ba, bx) \
(IcDoRRop(dst, fa, fx) & b) | (IcDoRRop(dst, ba, bx) & ~b)
#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
(FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
#define IcStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
(IcDoMaskRRop(dst, fa, fx, m) & (b)) | (IcDoMaskRRop(dst, ba, bx, m) & ~(b))
#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
(FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
#define IcDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
pixman_bits_t __xor = ((fx) & (b)) | ((bx) & ~(b)); \
IcDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
}
#define IcDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
pixman_bits_t __xor = ((fx) & (b)) | ((bx) & ~(b)); \
IcDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
}
#define IcOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
/*
* Compute rop for using tile code for 1-bit dest stipples; modifies
* existing rop to flip depending on pixel values
*/
#define IcStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
#define IcOpaqueStipple1Rop(alu,fg,bg) (IcStipple1RopPick(alu,fg) | \
(IcStipple1RopPick(alu,bg) << 2))
#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \
(FbStipple1RopPick(alu,bg) << 2))
#define IcStipple1Rop(alu,fg) (IcStipple1RopPick(alu,fg) | 4)
#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4)
#endif

Просмотреть файл

@ -22,7 +22,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "icint.h"
#include "pixman-xserver-compat.h"
#ifndef ICNOPIXADDR
/*
@ -31,7 +31,7 @@
* transparent stipple
*/
#define LaneCases1(c,a) case c: \
while (n--) { (void)IcLaneCase(c,a); a++; } \
while (n--) { (void)FbLaneCase(c,a); a++; } \
break
#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
@ -42,11 +42,11 @@
#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
#if IC_SHIFT == 6
#if FB_SHIFT == 6
#define LaneCases(a) LaneCases256(0,a)
#endif
#if IC_SHIFT == 5
#if FB_SHIFT == 5
#define LaneCases(a) LaneCases16(0,a)
#endif
@ -55,22 +55,22 @@
*/
void
IcTransparentSpan (pixman_bits_t *dst,
pixman_bits_t stip,
pixman_bits_t fgxor,
fbTransparentSpan (FbBits *dst,
FbBits stip,
FbBits fgxor,
int n)
{
IcStip s;
FbStip s;
s = ((IcStip) (stip ) & 0x01);
s |= ((IcStip) (stip >> 8) & 0x02);
s |= ((IcStip) (stip >> 16) & 0x04);
s |= ((IcStip) (stip >> 24) & 0x08);
#if IC_SHIFT > 5
s |= ((IcStip) (stip >> 32) & 0x10);
s |= ((IcStip) (stip >> 40) & 0x20);
s |= ((IcStip) (stip >> 48) & 0x40);
s |= ((IcStip) (stip >> 56) & 0x80);
s = ((FbStip) (stip ) & 0x01);
s |= ((FbStip) (stip >> 8) & 0x02);
s |= ((FbStip) (stip >> 16) & 0x04);
s |= ((FbStip) (stip >> 24) & 0x08);
#if FB_SHIFT > 5
s |= ((FbStip) (stip >> 32) & 0x10);
s |= ((FbStip) (stip >> 40) & 0x20);
s |= ((FbStip) (stip >> 48) & 0x40);
s |= ((FbStip) (stip >> 56) & 0x80);
#endif
switch (s) {
LaneCases(dst);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше