зеркало из https://github.com/mozilla/pjs.git
cairo landing: update to cairo 0.9.1+
This commit is contained in:
Родитель
afb71d6ee3
Коммит
65a80463ee
|
@ -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,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,173 +0,0 @@
|
|||
API Shakeup planning
|
||||
--------------------
|
||||
Patch submitted to mailing list?
|
||||
/ Documentation included in patch?
|
||||
|/ Review of patch completed?
|
||||
||/ Test case included?
|
||||
|||/ Committed.
|
||||
||||/
|
||||
New functionality (more-or-less)
|
||||
--------------------------------
|
||||
cairo_begin_group, cairo_end_group, cairo_get_group
|
||||
cairo_<device>_surface_mark_dirty
|
||||
Consistent error handling for all objects
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
* 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):
|
||||
|
||||
> void
|
||||
> cairo_text_glyphs (cairo_t *cr, const unsigned char *utf8,
|
||||
> cairo_glyph_t *glyphs, int *num_glyphs);
|
||||
>
|
||||
> with num_glyphs as an input-output parameter. The behavior of this
|
||||
> function would be such that calling:
|
||||
>
|
||||
> cairo_text_glyphs (cr, string, glyphs, &num_glyphs);
|
||||
> cairo_show_glyphs (cr, glyphs, num_glyphs);
|
||||
>
|
||||
> would be equivalent too:
|
||||
>
|
||||
> cairo_show_text (cr, string);
|
||||
>
|
||||
> as long as the original size of glyphs/num_glyphs was large
|
||||
> enough.
|
||||
|
||||
* Implement dashing for cairo_curve_to.
|
||||
|
||||
* 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
|
||||
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.
|
||||
|
||||
* 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, ®ion);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/* 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@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PATH_DATA_PRIVATE_H
|
||||
#define CAIRO_PATH_DATA_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
extern cairo_path_t _cairo_path_nil;
|
||||
|
||||
cairo_path_t *
|
||||
_cairo_path_data_create (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate);
|
||||
|
||||
cairo_path_t *
|
||||
_cairo_path_data_create_flat (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_data_append_to_context (cairo_path_t *path,
|
||||
cairo_t *cr);
|
||||
|
||||
#endif /* CAIRO_PATH_DATA_PRIVATE_H */
|
|
@ -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
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ictrap.c,v 1.3 2005-06-04 07:03:28 vladimir%pobox.com Exp $
|
||||
* $Id: ictrap.c,v 1.4 2005-08-20 05:34:02 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
|
@ -25,7 +25,7 @@
|
|||
#include "icint.h"
|
||||
|
||||
pixman_image_t *
|
||||
IcCreateAlphaPicture (pixman_image_t *dst,
|
||||
FbCreateAlphaPicture (pixman_image_t *dst,
|
||||
pixman_format_t *format,
|
||||
uint16_t width,
|
||||
uint16_t height)
|
||||
|
@ -167,7 +167,7 @@ pixman_composite_trapezoids (pixman_operator_t op,
|
|||
if (!format)
|
||||
return;
|
||||
|
||||
image = IcCreateAlphaPicture (dst, format,
|
||||
image = FbCreateAlphaPicture (dst, format,
|
||||
bounds.x2 - bounds.x1,
|
||||
bounds.y2 - bounds.y1);
|
||||
if (!image)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче