Commit graph

221 commits

Author SHA1 Message Date
Vladimir Vukicevic
9e975757a2 Export cairo_surface_{copy,show}_page
This patch adds cairo_surface_copy_page and cairo_surface_show_page
as public methods, leaving the previous cairo_show_page variants as
shorthands.  copy_page/show_page are specific to the surface, not
to the context, so they need to be surface methods.
2007-09-11 13:30:35 -07:00
Chris Wilson
c14cf02f61 [cairo-surface] Add a comment about why the glyph array is not const.
As penance for attempting to make the glyph array constant, add a
comment block to explain that the backends rely on being able to modify
the array.
2007-08-31 17:21:02 +01:00
Chris Wilson
e8e3bfc130 Revert "[cairo-gstate] Avoid copying untransformed glyphs."
This reverts commit 919bea6dbb.

Sadly as Behdad points out some backends do modify the glyph array and,
for example cairo-xlib-surface, hide this from the compiler with some
evil casts.
2007-08-31 16:53:21 +01:00
Chris Wilson
919bea6dbb [cairo-gstate] Avoid copying untransformed glyphs.
Skip the memory duplication of the incoming glyphs if we do not need
to transform them into the backend coordinate system.

As a consequence we need to constify the glyphs passed to the backend
functions.
2007-08-31 16:28:06 +01:00
Vladimir Vukicevic
93aee43690 Fix previous create_similar fallback patch
We can't use composite, as some backends don't implement it.
Use paint() instead.
2007-08-28 16:47:24 -07:00
Vladimir Vukicevic
69dae7ee4a Implement fallback for clone_similar 2007-08-28 10:54:19 -07:00
Emmanuel Pacaud
ac51fff0db Add a new fill_stroke surface backend method.
This method is for use in vector backends, where fill immediatly followed by
stroke command with the same path can be emited in the same backend command.
This commit also factorize the detection of such cases in the meta surface
backend and automatically call the fill_stroke method on replay.
2007-08-25 20:49:50 +02:00
Vladimir Vukicevic
0abe5324a5 [fixpt] Create cairo_region wrapper around pixman_region16_t
Insulate region-using code from implementation details;
at some point we'll want to switch to using 32-bit regions.
2007-07-18 22:46:46 +02:00
Vladimir Vukicevic
be3516335c [fixpt] Replace cairo_rectangle_int16_t with cairo_rectangle_int_t
Mostly s/cairo_rectangle_int16_t/cairo_rectangle_int_t/,
as well as definitions to pick cairo_rectangle_int_t.
2007-07-18 22:45:21 +02:00
Søren Sandmann Pedersen
ef967be630 Merge branch 'master' of git+ssh://sandmann@git.freedesktop.org/git/cairo
Conflicts:

	pixman/src/fbcompose.c
	pixman/src/icimage.c
	pixman/src/pixmanint.h
	pixman/src/pixregionint.h
	src/cairo-clip.c
2007-07-02 08:33:29 -07:00
Vladimir Vukicevic
5c7d2d14d7 [fix] Avoid int overflow when allocating large buffers
This patch introduces three macros: _cairo_malloc_ab,
_cairo_malloc_abc, _cairo_malloc_ab_plus_c and replaces various calls
to malloc(a*b), malloc(a*b*c), and malloc(a*b+c) with them.  The macros
return NULL if int overflow would occur during the allocation.  See
CODING_STYLE for more information.
2007-06-29 09:46:08 -07:00
Søren Sandmann
12cc32b674 [pixman] Initial port to standalone pixman library. 2007-06-21 22:21:11 -07:00
Adrian Johnson
99a6983017 Ensure surface backend finish() is never called more than once.
Previously if the backend finish() function returned an error status,
surface->finished was not set true. This would result in the backend
finish() function being called twice which in the case of the PostScript
backend caused a seg fault.
2007-05-17 10:17:09 +09:30
Chris Wilson
8ddfc1b2e4 [cairo-pattern] Return status from _cairo_pattern_init_copy()
During the copy, allocation of the gradient may fail and so the callers
need to check for a pattern that returned in an error state. No callers
did so and in order to force all callers to check the error status,
the status return was added to _cairo_pattern_init_copy().  The early
error checking may appear redundant for an object with an embedded
structure, however it does fix an error where an uninitialised pattern
was being used:

==1922== Process terminating with default action of signal 11 (SIGSEGV)
==1922==  Access not within mapped region at address 0x55555555
==1922==    at 0x402CF6F: _cairo_array_index (cairo-array.c:208)
==1922==    by 0x402D4F3: _cairo_user_data_array_fini (cairo-array.c:370)
==1922==    by 0x4046464: _cairo_pattern_fini (cairo-pattern.c:188)
==1922==    by 0x404992A: _cairo_meta_surface_paint (cairo-meta-surface.c:266)
==1922==    by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922==    by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922==    by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922==    by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922==    by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922==    by 0x804A4F7: draw (radial-gradient.c:73)
==1922==    by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922==    by 0x804A57C: main (radial-gradient.c:109)
==1922== Injected fault at:
==1922==    at 0x4020EA5: malloc (vg_replace_malloc.c:207)
==1922==    by 0x404475C: _cairo_pattern_init_copy (cairo-pattern.c:136)
==1922==    by 0x403F779: _cairo_surface_copy_pattern_for_destination (cairo-surface.c:2153)
==1922==    by 0x403FCC1: _cairo_surface_paint (cairo-surface.c:1328)
==1922==    by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922==    by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922==    by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922==    by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922==    by 0x804A4F7: draw (radial-gradient.c:73)
==1922==    by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922==    by 0x804A57C: main (radial-gradient.c:109)
2007-05-09 10:14:20 +01:00
Chris Wilson
21c6643b09 [cairo-surface] Check for errors when generating the scaled font.
cairo_surface_show_glyphs() attempts to generate a device specific
scaled font and so needs to check for failure before attempting to use
it.
2007-05-08 22:00:54 +01:00
Chris Wilson
ede76a97ea [cairo-font-options] Check for the nil-object.
The design is for the user to create a cairo_font_options_t object with
cairo_font_options_create() and then is free to use it with any Cairo
operation. This requires us to check when we may be about to overwrite
the read-only nil object.
2007-05-08 22:00:46 +01:00
Chris Wilson
a8c8e17d84 [cairo-pattern] Cache surface for solid patterns
Original work by Jorn Baayen <jorn@openedhand.com>,
2715f20981

We use a small cache of size 16 for surfaces created for solid patterns.
This mainly helps with the X backends where we don't have to create a
pattern for every operation, so we save a lot on X traffic.  Xft uses a
similar cache, so cairo's text rendering traffic with the xlib backend
now completely matches that of Xft.

The cache uses an static index variable, which itself acts like a cache of
size 1, remembering the most recently used solid pattern.  So repeated
lookups for the same pattern hit immediately.  If that fails, the cache is
searched linearly, and if that fails too, a new surface is created and a
random member of the cache is evicted.

A cached surface can only be reused if it is similar to the destination.
In order to check for similar surfaces a new test is introduced for the
backends to determine that the cached surface is as would be returned by
a _create_similar() call for the destination and content.

As surfaces are in general complex encapsulation of graphics state we
only return unshared cached surfaces and reset them (to clear any error
conditions and graphics state). In practice this makes little difference
to the efficacy of the cache during various benchmarks. However, in order
to transparently share solid surfaces it would be possible to implement a
COW scheme.

Cache hit rates:    (hit same index + hit in cache) / lookups
cairo-perf:         (42346 + 28480) / 159600 = 44.38%
gtk-theme-torturer: (3023  + 3502)  / 6528   = 99.95%
gtk-perf:           (8270  + 3190)  / 21504  = 53.29%

This translates into a reduction of about 25% of the XRENDER traffic during
cairo-perf.
2007-05-04 14:29:38 +01:00
Chris Wilson
3e3bd4df7e Minor typo in cairo_surface_destroy() documentation.
The type of @surface is #cairo_surface_t, not #cairo_t.
2007-05-01 11:28:45 +01:00
Carl Worth
29670d3766 Add a content value to solid patterns
This allows for the surface acquired from the pattern to have the
same content. In particular, in a case such as cairo_paint_with_alpha
we can now acquire an A8 mask surface instead of an ARGB32 mask
surface which can be rendered much more efficiently. This results
in a 4x speedup when using the OVER operator with the recently
added paint-with-alpha test:

Speedups
========
image-rgb  paint-with-alpha_image_rgb_over-256 2.25 -> 0.60: 4.45x speedup
███▌

It does slowdown the same test when using the SOURCE operator, but
I don't think we care. Performing SOURCE with a mask is already a very
slow operation, (hitting compositeGeneral), so the slowdown here is
likely from having to convert from A8 back to ARGB32 before the
generalized compositing. So if someone cares about this slowdown,
(though SOURCE with cairo_paint_with_alpha doesn't seem extremely
useful), they will probably be motivated enough to contribute a
customized compositing function to replace compositeGeneral in which
case this slowdown should go away:

image-rgba paint-with-alpha_image_rgb_source-256 3.84 -> 8.86%: 1.94x slowdown
█
2007-04-25 11:09:31 -07:00
Chris Wilson
41c6eebcd1 Optionally provide a pattern to use for creating a similar solid surface.
_cairo_surface_create_similar_solid() creates a fresh pattern to wrap
color, however sometimes the caller already has that pattern available.
In those circumstances we can pass the pattern as well as the color and
avoid the extra allocation.
2007-04-19 11:56:15 +01:00
Behdad Esfahbod
04164c996c [cairo-surface] Make sure cairo_surface_get_font_options() fully initializes
the font_options passed in.
2007-04-12 20:14:23 -04:00
Carl Worth
0f0ed88ee2 paginated: Add missing error check for _cairo_surface_show_page
Fixing this uncovered a leak of a CAIRO_INT_STATUS_UNSUPPORTED value
up to cairo_show_page, (and similarly to cairo_copy_page). There was
really no good reason for _cairo_surface_show_page and
_cairo_surface_copy_page to be returning cairo_int_status_t. Fix
this by simply handling the UNSUPPORTED return at the surface layer
instead of the gstate layer.
2007-04-10 23:01:55 -07:00
Carl Worth
01955a6e82 Rename ARRAY_LEN to ARRAY_LENGTH
Yet another victim in my hunt against abbreviations within cairo's implementation.
2007-04-10 10:14:49 -07:00
Behdad Esfahbod
6f93092217 Rename pixman_region_uninit to pixman_region_fini 2007-04-08 22:03:38 -04:00
Mathias Hasselmann
df9ea31df5 [pixman-region] Separate pixman_region_init
Most of the time pixman_region_init is called without any extents, and
followed by a pixman_region_union_rect, used to used to initialize
rectangular regions. pixman_region_union_rect is not that cheap, but
the sequence is called quite often. So it should be worth introducing
a specialized and fast function for this sequence.

This introduces pixman_region_init_rect.  This new function makes
_cairo_region_init_from_rectangle obsolete.

Also removes the extent argument from pixman_region_init as it was
called with NULL most of the time.  A pixman_region_init_with_extents
is added for the general case.
2007-04-08 21:49:46 -04:00
Mathias Hasselmann
241482b550 Avoid malloc in _cairo_region_create_from_rectangle 2007-04-08 21:12:02 -04:00
Mathias Hasselmann
0e7df34e07 Make region of cairo_clip_t static 2007-04-08 21:10:12 -04:00
Behdad Esfahbod
8fbf50d31d [src] Make sure all source files #include "cairoint.h" as their first include
This is necessary to avoid many portability problems as cairoint.h includes
config.h.  Without a test, we will regress again, hence add it.

The inclusion idiom for cairo now is:

	#include "cairoint.h"

	#include "cairo-something.h"
	#include "cairo-anotherthing-private.h"

	#include <some-library.h>
	#include <other-library/other-file.h>

Moreover, some standard headers files are included from cairoint.h and need
not be included again.
2007-04-03 20:28:11 -04:00
Behdad Esfahbod
ad51ee5aa0 Define and use ARRAY_LEN 2007-03-20 18:59:19 -04:00
Chris Wilson
1de12714a9 [cairo-surface] Use a stack buffer for small numbers of rectangles 2007-03-20 18:48:15 -04:00
Mathias Hasselmann
c4bd7cf6f8 Move declaration of cairo_mutex_t to cairo-mutex-private.h 2007-03-20 13:32:33 +01:00
Mathias Hasselmann
be52178443 Initialize mutexes at central location.
All mutex declarations have been moved to cairo-mutex-list.h.
This should avoid breaking of less frequently tested backends,
when mutexes are introduced or when existing mutexes are renamed.

Instead of initializing mutexes on library startup, mutexes are
lazily initialized within the few entry points of now by calling
CAIRO_MUTEX_INITIALIZE(). Currently only the OS/2 backend takes
care about releasing global mutexes. Therefore there is no counter
part of that macro for finalizing all global mutexes yet - but
as cairo-backend-os2.c shows such a function would be quite
easy to implement.
2007-03-20 10:11:14 +01:00
Carl Worth
725a4de42d Propagate a nil surface out of _cairo_surface_create_similar_scratch
We detect an error in the surface before calling into private surface-modifying
functions, (such as _cairo_surface_set_font_options), that don't have the
nil-surface protection of public functions.

This should fix the problem reported (again) in this bug report:

	cairo crashes in cairo_create_simular if nil surface returned by other->backend->create_similar
	https://bugs.freedesktop.org/show_bug.cgi?id=9844

Though I haven't succeeded in replicating the bug yet, (perhaps a system
difference in allowing writes to read-only memory or not, or something
like that).
2007-03-19 16:50:55 -07:00
Carl Worth
1234064fa4 Allow NULL pointers for functions that accept pointers for multiple return values.
When a single function accepts pointers for multiple return values,
the convention is that it's legal for the user to pass NULL for
those pointers in case the user is only interested in some subset
of the values.

This was already properly implemented for functions such as
cairo_pattern_get_rgba, etc.

Here we fix four functions to follow the same convention:

	cairo_stroke_extents
	cairo_fill_extents
	cairo_clip_extents
	cairo_surface_get_device_offset
2007-03-15 22:38:42 -07:00
Chris Wilson
789aada06b Avoid the struct copy when source and destination are the same.
On some architectures, gcc will emit a memcpy for structure copies which will
produce a valgrind warning when the source and destination pointers are the
same. Workaround this issue by explicitly checking the source and destination
for inequality before doing the structure assignment.
2007-03-12 14:48:05 -07:00
Behdad Esfahbod
4f138e4af5 Uniform object handling in _reference(), _destroy(), and _get_reference_count()
All three now regard NULL and nil inputs the same.  This is new for
_get_reference_count().  It now returns 0 on NULL too, like it does on
nil objects.
2007-03-05 16:28:31 -05:00
Behdad Esfahbod
1082fed692 [doc] Docuemnt all symbols but cairo_filter_t and cairo_operator_t
Lets see if this is enough to push Carl Worth document those two.
2007-03-02 22:42:17 -05:00
Behdad Esfahbod
9be961eb0c [doc] Some documentation love 2007-03-02 22:01:15 -05:00
Carl Worth
4e0f0d9425 Don't crash if backend->create_similar returns a nil surface
This fixes the bug reported here:

	cairo crashes in cairo_create_simular if nil surface returned by other->backend->create_similar
	https://bugs.freedesktop.org/show_bug.cgi?id=9844
2007-03-02 03:12:37 -08:00
Behdad Esfahbod
d0fe666a6a Revert the solid-pattern cache
This reverts the following commits:

	2715f20981
	67e3b3c53b

See this thread for an analysis of the problems it caused:

	http://lists.freedesktop.org/archives/cairo/2007-February/009825.html

In short, a single cache for all backends doesn't work, as one thread
using any backend can cause an unused xlib pattern to be evicted from
the cache, and trigger an xlib call while the display is being used
from another thread.  Xlib is not prepared for this.
2007-02-28 14:58:57 -05:00
Behdad Esfahbod
63c011bb6b [surface] Copy device_transform_inverse in _cairo_surface_clone_similar 2007-02-23 17:26:42 -05:00
Behdad Esfahbod
4e30919f30 [cairo-surface] Do not err on CAIRO_EXTEND_PAD and CAIRO_EXTEND_REFLECT
for surface patterns.

Right before releasing cairo 1.2, Carl and I decided to return error on
CAIRO_EXTEND_PAD and CAIRO_EXTEND_REFLECT for surface patterns, as they
are not implemented and one was causing crashes.  Well, that was probably
the worst decision we could make (other than ignoring the problem).  A
much better decision would have been to make them act like
CAIRO_EXTEND_NONE and CAIRO_EXTEND_REPEAT respectively.  Anyway, remove
the error paths.
2007-02-23 17:26:42 -05:00
Vladimir Vukicevic
5a72aac598 [core] put back REF_COUNT_INVALID to be -1, fix finish
Previous commit broke cairo_surface_finish, since it was checking for
ref_count == CAIRO_REF_COUNT_INVALID and bailing.  But, that condition
was reached from destroy, so finish was bailing out early.
2007-02-23 14:24:04 -08:00
Vladimir Vukicevic
cf73118522 [core] Add user_data and reference count getters to all objects
user_data setters/getters were added to public refcounted objects
that were missing them (cairo_t, pattern, scaled_font).  Also,
a refcount getter (cairo_*_get_reference_count) was added to all
public refcounted objects.
2007-02-23 13:05:23 -08:00
Jorn Baayen
2715f20981 [cairo-pattern] Cache surface for solid patterns
We use a small cache of size 16 for surfaces created for solid patterns.
This mainly helps with the X backends where we don't have to create a
pattern for every operation, so we save a lot on X traffic.  Xft uses a
similar cache, so cairo's text rendering traffic with the xlib backend
now completely matches that of Xft.

The cache uses an static index variable, which itself acts like a cache of
size 1, remembering the most recently used solid pattern.  So repeated
lookups for the same pattern hit immediately.  If that fails, the cache is
searched linearly, and if that fails too, a new surface is created and a
random member of the cache is evicted.

Only surfaces that are "compatible" are used.  The definition of compatible
is backend specific.  For the xlib backend, it means that the two surfaces
are allocated on the same display.  Implementations for compatibility are
provided for all backends that it makes sense.
2007-02-14 18:28:56 -08:00
Eugeniy Meshcheryakov
a37f21cb17 [PS/PDF/SVG] Return a write_error nil surface on write errors 2007-02-08 15:29:58 -08:00
Eugeniy Meshcheryakov
bf3cbe7660 [cairo-surface] Use a macro definition for all nil surfaces 2007-02-08 15:28:14 -08:00
Carl Worth
5d58e7ee66 Add scaled_font->mutex to allow locking for all subordinate objects
A cairo_scaled_font_t can be implicitly shared among multiple threads
as the same cairo_scaled_font_t can be returned from different calls
to cairo_scaled_font_create. To retain the illusion that these
different calls produce distinct objects, cairo must internally lock
access when modifying them.

Each glyph in the scaled font is represented by a cairo_surface_t
which is used when rendering the glyph. Instead of attempting to push
fine-grained locking of these surfaces down to the backend rendering
functions, a simple per-cairo_scaled_font_t lock has been introduced
which protects the entire rendering path against re-entrancy.

Some care was required to ensure that existing re-entrancy was handled
appropriately; these cases are in the wrapping surfaces
(cairo-paginated, test-meta and test-paginated).

Thanks to Vladimir Vukicev and Peter Weilbacher for testing/providing
the mutex definitions for win32 and os2 (respectively).
2007-02-06 17:53:27 -08:00
Carl Worth
c621201a41 Don't finish a finished surface in cairo_surface_destroy
Calling cairo_surface_finish from cairo_surface_destroy was
triggering an error due to finish being called twice. The
error was usually hidden as the surface would still eventually
be destroyed. But it did clutter things up quite badly if a
user was trying to break on _cairo_error to track down a
problem.

Thanks again to Stuart Parmenter <stuartp@gmail.com>
for pointing out the problem.
2007-02-01 16:05:59 -08:00
Carl Worth
159359325d Fix crashes in cairo_surface_finish for NULL or nil
Thanks to Stuart Parmenter for alerting us of this bug.
2007-02-01 15:22:27 -08:00