Commit graph

276 commits

Author SHA1 Message Date
Chris Wilson
b7272e9e8e [cairo-xlib] Batch XRenderFreeGlyphs
For every glyph evicted from the cache we would allocate a very small
structure to push onto the xlib work queue. This quickly becomes
noticably for an app that consumes a lot of scaled fonts and glyphs,
e.g. trying to draw text at various angles. So we maintain a small array
of glyphs pending finalisation and issue the XRenderFreeGlyphs() once the
array is full.
2008-05-06 15:11:00 +01:00
Chris Wilson
3428acf25d [cairo-scaled-font] Mark the scaled font as finished during destruction.
During the destruction of every font used with an xlib surface, we send
an XRenderFreeGlyphs() for every single glyph in the cache. These
requests are redundant as the server-side glyphs will be released along
with the XRenderFreeGlyphSet(), so we skip the individual glyph
destruction if the font is marked as finished.
2008-05-06 15:10:51 +01:00
Chris Wilson
24284c5101 [cairo-xlib] Enlarge the on-stack arrays.
Grow the on-stack arrays for the XRectangles and XTrapezoids to the
standard size in order to reduce the frequency of allocations.
2008-05-06 14:31:55 +01:00
Chris Wilson
fda9586802 [cairo-xlib] Cache standard xrender formats.
XRender performs a round-trip in order to query the available formats on
the xserver, before searching for a matching format. In order to save
that round-trip and to avoid the short-lived allocation of the array of
available formats, we cache the result on the display.
2008-05-06 14:31:45 +01:00
Chris Wilson
4924d4d928 [cairo-xlib] Do not create surface with mismatching Visual and PictFormat.
As identified by Vladimir Vukicevic,
_cairo_xlib_surface_create_similar_with_format() was erroneously passing
down the source Visual when creating a surface with a different
XRenderPictFormat.
2008-04-08 07:52:47 +01:00
Chris Wilson
f6afba8f54 [cairo-xlib] Create Pixmap using depth from xrender_format.
Use the depth as specified by the xrender_format when creating the
pixmap (as opposed to a guess based on the cairo_format_t).
2008-04-08 07:52:47 +01:00
Chris Wilson
922fefdde4 [cairo-xlib] Handle missing RENDER during similar surface creation
If the xserver doesn't support the RENDER extension or simply doesn't
have the matching PictFormat then xrender_format might be NULL. Check
and fallback in this case.
2008-04-08 07:52:46 +01:00
Chris Wilson
2c8ead12a6 [xlib] Avoiding sending glyphs > XMaxRequestSize.
XRenderAddGlyph() does not split its image data across multiple requests
and so the glyph surface must be smaller than XMaxRequestSize or else
the server will disconnect the client, causing "Fatal IO error 104".
As this will require an extension to the XRender spec, we can work
around the issue by using our fallbacks if we detect that the glyph will
be too large for a single request.

See bugs https://bugs.freedesktop.org/show_bug.cgi?id=4339 and
http://bugs.freedesktop.org/show_bug.cgi?id=13266 for examples.
2008-04-04 18:08:25 +01:00
Chris Wilson
eb3eb0252b [cairo-xlib-surface] Avoid writing to the error surface.
Insert status checks during construction of temporary glyph surfaces
to avoid potentially writing to the inert error object.
2008-04-02 17:33:30 +01:00
Chris Wilson
c1062bf20a [cairo-xlib-surface] Preserve Visuals for non-TrueColor similar surfaces.
Previously, given a valid XRenderFormat the Visual was discarded
when creating similar surfaces. However the original Visual is
required to support reading back from non-TrueColor surfaces.
2008-04-02 10:50:48 +01:00
Chris Wilson
37c69c0d54 [cairo-xlib] Handle malloc failures for cairo_xlib_visual_info_t.
Tidy the error paths whilst handling visuals, in particular avoiding a
couple of potential NULL deferences, missed status checks and fresh
leaks.
2008-04-02 10:50:48 +01:00
Carl Worth
46ea00d829 More quieting of subtle potentially-uninitialized warnings
The compiler isn't clever enough to notice that these
variables are always initialized (in either the TrueColor
or ! TrueColor conditions corresponding to the later
identical conditions in which the variables are used).
2008-04-01 14:53:55 -07:00
Carl Worth
d7e5f6b6a0 Rename _popcount to _cairo_popcount and make it available for internal use
Both cairo-image-surface.c and cairo-xlib-surface.c want to
use this function now.
2008-03-25 16:32:24 -07:00
Carl Worth
e96f382549 Add support for 8-bit PseudoColor visuals
This support involves allocating a 16-bit grayscale ramp as well
as a 5x5x5 RGB color cube. Afterwards, the 256 colors are queried
and an array is generated mapping from r3g3b3 colors to the closest
available color. Both the queried colors and the reverse mapping
are stored in a new visual-specific cairo_xlib_visual_info_t
structure which hangs off of the cairo_xlib_screen_info_t.

Both the color-cube allocation and the distance metric could be
improved by someone sufficiently motivated, (for example, allocating
and matching in a perceptually linear color space rather than just
in RGB space). Also, making this work well in the face of a changing
color map, or in the case of GrayScale, StaticGray, or DirectColor
visuals are left entirely as exercises for the reader. StaticColor
support should be fine as is, but is entirely untested.
2008-03-20 11:51:57 -07:00
Carl Worth
d413c5ab21 xlib: Add support for arbitrary TrueColor visuals
This fixes the following bugs:

	cairo doesn't support 8-bit truecolor visuals
	https://bugs.freedesktop.org/show_bug.cgi?id=7735

	cairo doesn't support 655 xlib format
	https://bugs.freedesktop.org/show_bug.cgi?id=9719
2008-03-20 11:51:57 -07:00
Carl Worth
eb31c52feb Make _pixman_format_to_masks accept a cairo_format_masks_t structure
This makes it work similarly to _pixman_format_from_masks
2008-03-18 17:20:08 -07:00
Carl Worth
cdb1ae97f2 Move assertion failure for unsupported masks up one level
We're moving the assertion up from inside _pixman_format_to_mask
to its callers. This will allow us to selectively eliminate the
assertion from the supported xlib backend, while leaving it in
the unsupported glitz and xcb backends for now.
2008-03-18 17:20:08 -07:00
Chris Wilson
c985096e6d [cairo-xlib] Tidy usage of _cairo_error().
Avoid a duplicate call to _cairo_error() and add a missing one.
2008-03-04 09:31:20 +00:00
Behdad Esfahbod
e68584d3a1 [xlib] Move multiple CAIRO_MUTEX_INITIALIZE into one place they all end up anyway 2008-02-08 17:37:50 -05:00
Carl Worth
ac743e25fa cairo_xlib_surface_create_similar: Pass the original drawable to XCreatePixmap
Previously we were passing the root window of the same screen.
Letting the X server know the actual Drawable for which we're
trying to be similar allows the X server to be more efficient.
2008-02-06 17:01:21 -08:00
Behdad Esfahbod
9d8990b6bd [doc] Remove excess paranthesis 2008-01-28 23:23:00 -05:00
Behdad Esfahbod
b790c5a6bc [doc] Replace 'NOTE' by 'Note' and add it to test 2008-01-28 21:53:44 -05:00
Behdad Esfahbod
c133ee5acc [doc] Improve docs for new API 2008-01-28 21:00:21 -05:00
Behdad Esfahbod
0d898f2bad [doc] Make sure all type names in docs are prefixed by # 2008-01-28 20:49:44 -05:00
Behdad Esfahbod
9ecde82d35 [doc] Make sure all macro names in docs are prefixed by % 2008-01-28 20:48:48 -05:00
Carl Worth
cc94dce250 Return NULL from cairo_xlib_surface_get_xrender_format without an error
The NULL return value will only happen if the X Render extension
is not available. We've already got that NULL return value
documented, so it's not an error if the user asks for it. In
particular, it's definitely not a surface-type mismatch.
2008-01-28 15:39:39 -08:00
Carl Worth
3c018a6e5a Add new API cairo_xlib_surface_get_render_format 2008-01-28 15:39:39 -08:00
Vladimir Vukicevic
02970ac8cf Fix usage of cairo_rectangle_int16_t leading to memory corruption
cairo_rectangle_int16_t was being used in a number of places instead
of cairo_rectangle_int_t, which led to memory corruption when cairo was
using a fixed point format with a bigger space than 16.16 (such as 24.8).
2008-01-22 15:32:11 -08:00
Chris Wilson
7111b18c27 [cairo-surface] Introduce _cairo_surface_create_in_error().
Unexport all the static error surfaces and use a function to select
the appropriate error surface for the status.
2008-01-16 16:51:32 +00:00
Chris Wilson
968eaf3c44 [cairo-xlib] Fixup --disable-xlib-xrender
Fixup the headers and boilerplate to compile and run correctly when
configured with --disable-xlib-xrender.
2008-01-15 13:08:53 +00:00
Chris Wilson
8343d6cc2a Replace various uses of CAIRO_STACK_BUF_SIZE with a single macro.
In http://bugs.freedesktop.org/show_bug.cgi?id=13699, Pavel Vozenilek
reports a duplicate define for computing the appropriate length for an
on-stack array. The macro in question, and a few other places, was
performing CAIRO_STACK_BUF_SIZE/sizeof(stack[0]) so we can simplify
them slightly by using a common macro.
2007-12-17 13:45:01 +00:00
Behdad Esfahbod
9637ffc62f [cairo-xlib] Minor cleanup and add comment 2007-12-17 01:55:15 -05:00
Behdad Esfahbod
805b668260 [cairo-xlib] Support scale fonts with glyphs of multiple formats (#13479)
We maintain three Xrender glyphsets per scaled font, one for each of A1, A8,
and ARGB32.  This is required to correctly support fonts with bitmaps for
some glyphs but not all.
2007-12-17 01:14:45 -05:00
Chris Wilson
3211d810d3 [cairo-xlib] Check source for XRender support.
Do not rely on the assumption that if the destination has render support
then the source has it as well - breaks when the boilerplate disables
render support for a surface.

Similarly do not set the XRender attributes on the source surface
unless it actually has a xrender_format.
2007-10-19 23:33:22 +01:00
Behdad Esfahbod
76e3b3cdc3 [cairo-xlib] Release glyph surfaces if we made them to be generated
The reasoning is that right now, applications render glyphs to images,
upload it to the X server, and keep a local copy in the cache.  The X
server works hard to reuse glyph renderings, by hashing glyph images and
reusing them.  So we are wasting memory in cairo apps that don't use the
glyph surface after uploading to the server, which is the case if you
don't use the glyph in an image surface.  The patch does not release the
glyph surface if it already existed in the cache, so, worst case
scenario is that we render the glyph twice, if you first use it with
xlib, then with image surface.  That effect should be negligible.
2007-10-19 15:02:03 -04:00
Chris Wilson
8ae7782737 [cairo-xlib-surface] Match content to xrender_format using the channel masks.
_xrender_format_to_content() was using the channel offset to determine
whether the format supported a content type.
For example, the XRenderPictFormat for the A8 format looks like:
    direct.alpha = 0; direct.alphaMask = 0xff;
    direct.red   = 0; direct.redMask   = 0x00;
    direct.green = 0; direct.greenMask = 0x00;
    direct.blue  = 0; direct.blueMask  = 0x00;
which _xrender_format_to_content() matched as CAIRO_CONTENT_COLOR.

Switch to using the channel masks for deducing content type.
2007-10-18 20:09:54 +01:00
Chris Wilson
379b9b79fa [cairo-xlib] Move the buggy_repeat discovery to the display_t.
The VendorString parsing (to detect broken Xserver versions) was being
performed for each surface creation, but as it is a display invariant
we can save a small amount of work by storing the result on the
cairo_xlib_display_t.
2007-10-18 19:21:01 +01:00
Chris Wilson
4958789b9e [cairo-xlib-surface] Propagate error from _draw_image_surface() to surface.
Instead of simply ignoring the error that may occur when we upload the
destination image to the xlib surface (via XPutImage) record the error
on the xlib surface.
2007-10-10 14:22:49 +01:00
Chris Wilson
2f22510e22 [cairo-xlib] Initialize the global mutexes.
The xlib surface creation routines will eventually attempt to lock the
global _cairo_xlib_display_mutex. Under the default environment this is
a non-issue as the CAIRO_MUTEX_INITIALIZE/FINALIZE become no-ops under
pthreads. However, for the sake of correctness (i.e. to silence the
lockdep debugger!) insert a call to initialize the global mutexes at the
start of the public entry points.
2007-10-05 16:25:02 +01:00
Chris Wilson
bed8239f03 [cairo-error] Clean up all the warnings and missing _cairo_error() calls.
Every time we assign or return a hard-coded error status wrap that value
with a call to _cairo_error(). So the idiom becomes:
    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
or
    return _cairo_error (CAIRO_STATUS_INVALID_DASH);

This ensures that a breakpoint placed on _cairo_error() will trigger
immediately cairo detects the error.
2007-10-04 13:31:44 +01:00
Chris Wilson
8ad56b308a [malloc/error] Add call to _cairo_error() after a failed malloc.
Blitz all allocations to ensure that they raise a
_cairo_error(CAIRO_STATUS_NO_MEMORY) on failure.
2007-10-04 00:42:30 +01:00
Behdad Esfahbod
740fed62d2 [xlib] Make it compile without Xrender available at compile time (#12210) 2007-08-31 20:52:43 -04: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
Carl Worth
72fab3675c Use a pixman_format_code to describe the image surface used for xlib fallbacks
Previously, the code was just using cairo_format_t which is much more limited
than the formats supported by pixman, (so many "odd" X server visuals would
just fall over).
2007-08-21 17:10:49 -07:00
Behdad Esfahbod
31f5aafa36 Fix device_offset misuse in all glyph surface uses
Seems like all over the code, we have been using negated device_offset
values for glyph surfaces.  Here is all the math(!):

A device_transform converts from device space (a conceptual space) to
surface space.  For simple cases of translation only, it's called a
device_offset and is public API (cairo_surface_[gs]et_device_offset).
A possibly better name for those functions could have been
cairo_surface_[gs]et_origing.  So, that's what they do: they set where
the device-space origin (0,0) is in the surface.  If the origin is inside
the surface, device_offset values are positive.  It may look like this:

Device space:
      (-x,-y) <-- negative numbers
         +----------------+
         |      .         |
         |      .         |
         |......(0,0) <---|-- device-space origin
         |                |
         |                |
         +----------------+
                  (width-x,height-y)

Surface space:
       (0,0) <-- surface-space origin
         +---------------+
         |      .        |
         |      .        |
         |......(x,y) <--|-- device_offset
         |               |
         |               |
         +---------------+
                   (width,height)

In other words: device_offset is the coordinates of the device-space
origin relative to the top-left of the surface.

We use device offsets in a couple of places:

  - Public API: To let toolkits like Gtk+ give user a surface that
    only represents part of the final destination (say, the expose
    area), but has the same device space as the destination.  In these
    cases device_offset is typically negative.  Example:

         application window
         +---------------+
         |      .        |
         | (x,y).        |
         |......+---+    |
         |      |   | <--|-- expose area
         |      +---+    |
         +---------------+

    In this case, the user of cairo API can set the device_space on
    the expose area to (-x,-y) to move the device space origin to that
    of the application window, such that drawing in the expose area
    surface and painting it in the application window has the same
    effect as drawing in the application window directly.  Gtk+ has
    been using this feature.

  - Glyph surfaces: In most font rendering systems, glyph surfaces
    have an origin at (0,0) and a bounding box that is typically
    represented as (x_bearing,y_bearing,width,height).  Depending on
    which way y progresses in the system, y_bearing may typically be
    negative (for systems similar to cairo, with origin at top left),
    or be positive (in systems like PDF with origin at bottom left).
    No matter which is the case, it is important to note that
    (x_bearing,y_bearing) is the coordinates of top-left of the glyph
    relative to the glyph origin.  That is, for example:

    Scaled-glyph space:

      (x_bearing,y_bearing) <-- negative numbers
         +----------------+
         |      .         |
         |      .         |
         |......(0,0) <---|-- glyph origin
         |                |
         |                |
         +----------------+
                  (width+x_bearing,height+y_bearing)

    Note the similarity of the origin to the device space.  That is
    exactly how we use the device_offset to represent scaled glyphs:
    to use the device-space origin as the glyph origin.

Now compare the scaled-glyph space to device-space and surface-space
and convince yourself that:

	(x_bearing,y_bearing) = (-x,-y) = - device_offset

That's right.  If you are not convinced yet, contrast the definition
of the two:

	"(x_bearing,y_bearing) is the coordinates of top-left of the
	 glyph relative to the glyph origin."

	"In other words: device_offset is the coordinates of the
	 device-space origin relative to the top-left of the surface."

and note that glyph origin = device-space origin.

So, that was the bug.  Fixing it removed lots of wonders and magic
negation signs.

The way I discovered the bug was that in the user-font API, to make
rendering the glyph from meta-surface to an image-surface work I had
to do:

	cairo_surface_set_device_offset (surface, -x_bearing, -y_bearing);
	_cairo_meta_surface_replay (meta_surface, surface);
	cairo_surface_set_device_offset (surface, x_bearing, y_bearing);

This suggested that the use of device_offset for glyph origin is
different from its use for rendering with meta-surface.  This reminded
me of the large comment in the xlib backend blaming XRender for having
weird glyph space, and of a similar problem I had in the PS backend
for bitmap glyph positioning (see d47388ad75)

...those are all fixed now.
2007-08-20 21:01:55 -04:00
Chris Wilson
507d7ee099 [cairo-xlib-surface] Avoid a malloc(0).
Avoid a zero byte allocation (potentially returning NULL) for an array
of 0 trapezoids.
2007-08-16 15:37:13 +01:00
Vladimir Vukicevic
c0a7d33ac6 [fixpt] Fixup malloc usage to use _cairo_malloc_*
Fix some introduced mallocs as a result of the fixed point patches.
2007-07-18 22:46:46 +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
58d9664702 [fixpt] Fix xlib surface to handle conversion to 16.16 2007-07-18 22:45:22 +02:00