Merge branch 'master' of ssh+git://git.cairographics.org/git/cairo

This commit is contained in:
Michael Emmel 2006-08-02 14:32:50 -07:00
commit c05dd48ac1
18 changed files with 331 additions and 450 deletions

View file

@ -60,6 +60,9 @@ More detailed build instructions
LD_LIBRARY_PATH=/opt/cairo/lib
export PKG_CONFIG_PATH LD_LIBRARY_PATH
(NOTE: On mac OS X, at least, use DYLD_LIBRARY_PATH in place
of LD_LIBRARY_PATH above.)
--enable-ps
--enable-pdf
--enable-quartz

199
ROADMAP
View file

@ -17,13 +17,13 @@ it to indicate you are working on it.
Targets
=======
GTK+ 2.10 - http://www.gtk.org/plan/2.10/
------------------------------------------
The 2.10 release is scheduled for May 2006, (to be in time for GNOME 2.16).
Satisfying GTK+ 2.10 well requires releasing cairo 1.2 with good
printing support, (good PS/PDF output, per-page sizing and layout,
etc.) sometime in April 2006.
GNOME 2.16 (http://live.gnome.org/TwoPointFifteen)
--------------------------------------------------
With cairo 1.2 already part of GTK+ 2.10, we want to make sure that
the cairo used in GNOME 2.16 is as good as possible. The final date
for 2.16 is September 6, 2006 but the deadline of interest to us is
the tarball due date for next beta (2.16.0 Beta 2 -- 2.15.91) which is
August 7, 2006.
Firefox 3.0 - http://www.mozilla.org/projects/firefox/roadmap.html
------------------------------------------------------------------
@ -33,122 +33,73 @@ cairo are available
Satisfying firefox 3 well requiring releasing new versions of cairo
before November 2006 (or earlier) that incorporate the patches coming
from mozilla, (device offset, push/pop_group), and much-improved
performance.
from mozilla, (clip querying), and much-improved performance.
Themes and Schedules
====================
cairo-1.2 (April 2006): Better printing
- Supported PS/PDF output
- New, printing-oriented API
- Mozilla patches (device offset, push/pop_group)
cairo-1.2.2 (August 7, 2006): Fix the bad bugs in 1.2.0
- Fix failure on BGR X servers
- Fix the disappearing text bugs
cairo-1.4 (October 2006): Better performance
- New tessellator
- New rasterization
- Finer-grained fallbacks for PS/PDF
cairo 1.2.0 plans
cairo 1.2.2 plans
=================
✓xlib backend
✓add cairo_xlib_surface_get_width/height
Blocker bugs (For each XXXX, see: https://bugs.freedesktop.org/show_bug.cgi?id=XXXX )
✓6617 With cairo 1.0.4 some text just disappears
7294 cairo doesn't work with a BGR X server visual (assertion ...
✓7494 non-antialiased xlib text doesn't appear after first space
7497 _cairo_color_compute_shorts fails with FPU set to single ...
7514 libcairo 1.2.0 much much slower than 1.0.4 on an ssh conn...
7533 Image fallbacks have incorrect transforms
7538 PDF backend introduces FreeType dependency
✓Bug fixes (For each XXXX, see: https://bugs.freedesktop.org/show_bug.cgi?id=XXXX )
✓6759 fontconfig option AntiAlias doesn't work in cairo 1.1.2
✓6955 Some characters aren't displayed when using xlib (cache u...
✓7268 positive device_offset values don't work as source
✓ PDF emit_glyph function needs to support bitmapped glyphs
✓ PS emit_glyph function needs to support bitmapped glyphs
✓ SVG emit_glyph function needs to support bitmapped glyphs
✓ PDF: minefield page one is falling back unnecessarily
✓ should be possible to draw caps with degenerate paths
cairo 1.4.0 ideas (think performance!)
======================================
Implement framework for performance regression testing
✓Fix memory leaks
✓1. Ensure 'make check-valgrind' passes with no leaks (mostly done)
Investigate "low-hanging fruit" identified by David Turner (write test case for each)
Bugs that might already be fixed anyway
---------------------------------------
6617 With cairo 1.0.4 some text just disappears
Look into speeding up pixman gradients
Bugs that won't be fixed
------------------------
Look into improving text positioning/placement on ARM (with no hardware floating-point)
Look into speeding up dashing used for GTK+ focus rectangle
Look into other GTK+ performance regressions as identified on performance-list
xlib backend
Switch to server-side gradients for xlib backend
Fix X server to make server-side gradients faster
Switch to using XRenderAddTraps rather than XRenderCompositeTrapezoids
Implement a non-trapezoid based rasterizer for use with xlib and other backends
Cull geometry outside clip region bounds
New tessellator
Unscheduled stuff we'd like to get to at some point
===================================================
Fairly severe bugs
6806 cairo 1.0.4 crash progressbar in window
PDF: minefield shows too-tiny bitmapped fonts in image fallback
PDF: minefield shows strangely hinted glyph shapes (only without truetype subsetting)
PDF: minefield has broken selection (only with truetype subsetting code)
4630 Fonts too large when drawing to image surface while printing
4863 stroking problems with wide dashed lines
cairo 1.1.10 snapshot includes everything below here
----------------------------------------------------
✓Bug fixes
✓7229 assertion failure in _cairo_content_from_format on 16-bit X server
Fix all expected failures (XFAIL) in the test suite
a8-mask
extend-reflect
filter-nearest-offset
leaky-dash
self-intersecting
text-rotate
✓SVG backend
✓rewrite to not require libxml2
cairo 1.1.8 snapshot includes everything below here
---------------------------------------------------
✓PDF backend
✓1. Mark PDF backend as supported
✓a. Incorporate into test suite
✓b. Correct output for the entire test suite
✓2. Reasonable, native output for common uses
✓a. Switch to using cairo_paginated_surface_t
✓b. Opaque text and images are all native
✓c. Translucent objects (using OVER) are also native
✓d. Text output uses PDF font features (type 3)
✓Bug fixes with API implications
✓ cairo_{ps,pdf}_surface_set_dpi have no effect (replace with cairo_surface_set_fallback_resolution)
✓ cairo_set_line_width semantics (that's not a bug, it's a feature)
✓Bug fixes (For each XXXX, see: https://bugs.freedesktop.org/show_bug.cgi?id=XXXX )
✓ FC_GLOBAL_ADVANCE (http://lists.freedesktop.org/archives/cairo/2005-August/004893.html)
✓4705 crash at XRenderAddGlyphs
✓ _transform_glyph_bitmap http://lists.freedesktop.org/archives/cairo/2005-October/005564.html
cairo 1.1.6 snapshot includes everything below here
---------------------------------------------------
✓Printing-oriented API (PDF)
✓1. Per-page size settings
✓Mozilla needs
✓1. Device-offset rework
✓2. Push/pop_group
cairo 1.1.4 snapshot includes everything below here (and cairo 1.1.2 some of these)
-----------------------------------------------------------------------------------
✓Printing-oriented API (PostScript)
✓1. Per-page settings (paper size, layout, anything else?)
✓2. Document metadata
✓PS backend
✓1. Mark PS backend as supported:
✓a. Incorporate into test suite
✓b. Correct output for the entire test suite
✓2. Reasonable, native output for common uses
✓a. Switch to using cairo_paginated_surface_t
✓b. Opaque text and images are all native
✓c. Text output uses PostScript font features
✓Pango needs
✓5496 Add getters for cairo_scaled_font_t
✓5495 Need cairo_scaled_font_text_extents
✓SVG backend
✓1. Add experimental SVG backend
✓2. Incorporate into test suite
✓Performance improvements
✓1. Speed up glyph measurement (cache rewrite)
✓2. Speed up gradient computations
✓a. Better software gradients
cairo 1.2.0 desired features
If these aren't ready, they won't be in the release.
======================================================
Win32 backend
✓1. Incorporate into test suite
2. Correct output for the entire suite
@ -157,39 +108,11 @@ If these aren't ready, they won't be in the release.
[There is some mailing-list discussion about possible fixes
for these.]
Mozilla patches
1. Misc compilation fixes for pixman (submitted upstream)
2. mac compilation fix for cairo-atsui-font.c for 10.2 SDK (maybe should
be upstream?)
3. Make mark_dirty() reset a surface's clip, so that we can call it
when we RestoreDC() after native win32 drawing (submitted upstream)
4. Rework win32 surface clip and extents handling for correctness
(submitted upstream)
5. Add GdiFlush() calls before each image surface get
(Submitted upstream: https://bugs.freedesktop.org/show_bug.cgi?id=5845)
Bug fixes
4630 Fonts too large when drawing to image surface while printing
4863 stroking problems with wide dashed lines
Fix some expected failures (XFAIL) in the test suite
a. a8-mask
✓b. clip-all
c. filter-nearest-offset
d. pixman-rotate
e. extend-reflect
New API
cairo_arc_to
see http://lists.freedesktop.org/archives/cairo/2005-August/004801.html
or see arc_to branch in bedhad's repository
Performance improvements
1. Cull and trim trapezoids outside clip region bounds
2. Generate more large pixel-aligned, rectangular trapezoids
3. Use X server gradients when available
Longer-term desired stuff for cairo (not scheduled for any particular release)
==============================================================================
PS/PDF improvements
1. Make image fallbacks finer-grained than a whole page
2. Ensure that PDF text output is "selectable"
@ -198,17 +121,3 @@ Longer-term desired stuff for cairo (not scheduled for any particular release)
1. Mark Quartz backend as supported:
a. Incorporate into test suite
b. Correct output for the entire suite
SVG backend
1. Correct output for the entire test suite
Performance improvements
1. New tessellator (more robust and faster)
Bug fixes
1. Fix all expected failures (XFAIL) in the test suite
a. self-intersecting
AKA. https://bugs.freedesktop.org/show_bug.cgi?id=3752
Fix depends on [A1].
b. text-rotate

View file

@ -170,4 +170,6 @@ do_cmd $AUTOCONF
cd $ORIGDIR || exit 1
rm -f config.cache
do_cmd $srcdir/configure --cache-file=config.cache --disable-static --enable-maintainer-mode --enable-gtk-doc ${1+"$@"} && echo "Now type \`make' to compile" || exit 1

View file

@ -104,7 +104,10 @@ dnl backend-specific .pc file.
dnl COMMANDS are run to check whether the backend can be enabled. Their
dnl result may be cached, so user should not count on them being run.
dnl They should set use_$(NAMESPACE) to something other than yes if the
dnl backend cannot be built, eg. "no (requires SomeThing)"
dnl backend cannot be built, eg. "no (requires SomeThing)". It then
dnl should also set $(NAMESPACE)_REQUIRES/CFLAGS/LIBS/...
dnl appropriately. Look at the macro definition for more details,
dnl or ask if in doubt.
dnl
AC_DEFUN([CAIRO_BACKEND_ENABLE],
[AC_ARG_ENABLE([$3],
@ -241,7 +244,7 @@ CAIRO_BACKEND_ENABLE(quartz, Quartz, quartz, QUARTZ_SURFACE, no, [
dnl ===========================================================================
CAIRO_BACKEND_ENABLE(xcb, XCB, xcb, XCB_SURFACE, no, [
xcb_REQUIRES="xcb xcb-render"
xcb_REQUIRES="xcb xcb-render xcb-renderutil"
PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, , [
use_xcb="no (requires XCB http://xcb.freedesktop.org)"])
])

View file

@ -88,7 +88,7 @@ sgml.stamp: sgml-build.stamp
#### html ####
dist-hook install-data-local: html-build.stamp
dist-hook-local: html-build.stamp
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
@echo 'gtk-doc: Building HTML'

View file

@ -1,6 +1,5 @@
font_subset_sources = \
cairo-font-subset.c \
cairo-font-subset-private.h \
cairo-type1-subset.c \
cairo-scaled-font-subsets.c \
cairo-scaled-font-subsets-private.h

View file

@ -1,67 +0,0 @@
/* 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 */

View file

@ -31,6 +31,7 @@
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Adrian Johnson <ajohnson@redneon.com>
*/
#include "cairoint.h"
@ -69,6 +70,9 @@ typedef struct _cairo_ft_font {
FT_Face face;
int checksum_index;
cairo_array_t output;
cairo_array_t string_offsets;
unsigned long last_offset;
unsigned long last_boundary;
int *parent_to_subset;
cairo_status_t status;
@ -80,6 +84,7 @@ cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
#define SFNT_VERSION 0x00010000
#define SFNT_STRING_MAX_LENGTH 65535
#ifdef WORDS_BIGENDIAN
@ -158,6 +163,8 @@ _cairo_pdf_ft_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
font->last_offset = 0;
font->last_boundary = 0;
_cairo_array_init (&font->output, sizeof (char));
if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)
goto fail1;
@ -192,6 +199,10 @@ _cairo_pdf_ft_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (font->base.widths == NULL)
goto fail5;
_cairo_array_init (&font->string_offsets, sizeof (unsigned long));
if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS)
goto fail6;
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
font->status = CAIRO_STATUS_SUCCESS;
@ -200,6 +211,8 @@ _cairo_pdf_ft_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
return CAIRO_STATUS_SUCCESS;
fail6:
free (font->base.widths);
fail5:
free (font->base.base_font);
fail4:
@ -222,6 +235,7 @@ cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font)
free (font->parent_to_subset);
free (font->glyphs);
_cairo_array_fini (&font->output);
_cairo_array_fini (&font->string_offsets);
free (font);
}
@ -287,6 +301,16 @@ cairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font)
return aligned;
}
static void
cairo_pdf_ft_font_check_boundary (cairo_pdf_ft_font_t *font, unsigned long boundary)
{
if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) {
_cairo_array_append(&font->string_offsets, &font->last_boundary);
font->last_offset = font->last_boundary;
}
font->last_boundary = boundary;
}
static int
cairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag)
{
@ -389,7 +413,7 @@ cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
{
cairo_status_t status;
unsigned long start_offset, index, size;
unsigned long start_offset, index, size, next;
TT_Header *header;
unsigned long begin, end;
unsigned char *buffer;
@ -427,8 +451,10 @@ cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
size = end - begin;
font->glyphs[i].location =
cairo_pdf_ft_font_align_output (font) - start_offset;
next = cairo_pdf_ft_font_align_output (font);
cairo_pdf_ft_font_check_boundary (font, next);
font->glyphs[i].location = next - start_offset;
status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);
if (status)
break;
@ -681,7 +707,8 @@ cairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned l
static cairo_status_t
cairo_pdf_ft_font_generate (void *abstract_font,
const char **data, unsigned long *length)
const char **data, unsigned long *length,
const unsigned long **string_offsets, unsigned long *num_strings)
{
cairo_ft_unscaled_font_t *ft_unscaled_font;
cairo_pdf_ft_font_t *font = abstract_font;
@ -711,6 +738,7 @@ cairo_pdf_ft_font_generate (void *abstract_font,
next = cairo_pdf_ft_font_align_output (font);
cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,
start, end);
cairo_pdf_ft_font_check_boundary (font, next);
start = next;
}
@ -721,6 +749,11 @@ cairo_pdf_ft_font_generate (void *abstract_font,
*data = _cairo_array_index (&font->output, 0);
*length = _cairo_array_num_elements (&font->output);
*num_strings = _cairo_array_num_elements (&font->string_offsets);
if (*num_strings != 0)
*string_offsets = _cairo_array_index (&font->string_offsets, 0);
else
*string_offsets = NULL;
fail:
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
@ -748,8 +781,11 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_pdf_ft_font_t *font;
cairo_status_t status;
const char *data = NULL; /* squelch bogus compiler warning */
unsigned long parent_glyph, length = 0; /* squelch bogus compiler warning */
unsigned long length = 0; /* squelch bogus compiler warning */
unsigned long parent_glyph, offsets_length;
int i;
const unsigned long *string_offsets = NULL;
unsigned long num_strings = 0;
status = _cairo_pdf_ft_font_create (font_subset, &font);
if (status)
@ -760,7 +796,8 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_pdf_ft_font_use_glyph (font, parent_glyph);
}
status = cairo_pdf_ft_font_generate (font, &data, &length);
status = cairo_pdf_ft_font_generate (font, &data, &length,
&string_offsets, &num_strings);
if (status)
goto fail1;
@ -788,10 +825,20 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
memcpy (truetype_subset->data, data, length);
truetype_subset->data_length = length;
offsets_length = num_strings * sizeof (unsigned long);
truetype_subset->string_offsets = malloc (offsets_length);
if (truetype_subset->string_offsets == NULL)
goto fail4;
memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
truetype_subset->num_string_offsets = num_strings;
cairo_pdf_ft_font_destroy (font);
return CAIRO_STATUS_SUCCESS;
fail4:
free (truetype_subset->data);
fail3:
free (truetype_subset->widths);
fail2:
@ -808,5 +855,6 @@ _cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
free (subset->base_font);
free (subset->widths);
free (subset->data);
free (subset->string_offsets);
}

View file

@ -492,7 +492,7 @@ _cairo_gstate_get_line_join (cairo_gstate_t *gstate)
}
cairo_status_t
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset)
{
int i;
double dash_total;
@ -1436,10 +1436,12 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
for (i = 0; i < num_glyphs; ++i)
{
transformed_glyphs[i] = glyphs[i];
_cairo_gstate_user_to_device (gstate,
&transformed_glyphs[i].x,
&transformed_glyphs[i].y);
transformed_glyphs[i].index = glyphs[i].index;
transformed_glyphs[i].x = glyphs[i].x + gstate->font_matrix.x0;
transformed_glyphs[i].y = glyphs[i].y + gstate->font_matrix.y0;
_cairo_gstate_user_to_backend (gstate,
&transformed_glyphs[i].x,
&transformed_glyphs[i].y);
}
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);

View file

@ -424,6 +424,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
cairo_truetype_subset_t subset;
cairo_status_t status;
int i;
unsigned int begin, end;
status = _cairo_truetype_subset_init (&subset, font_subset);
if (status)
@ -464,17 +465,27 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
_cairo_output_stream_printf (surface->final_stream,
"end readonly def\n");
/* FIXME: We need to break up fonts bigger than 64k so we don't
* exceed string size limitation. At glyph boundaries. Stupid
* postscript. */
_cairo_output_stream_printf (surface->final_stream,
"/sfnts [<");
_cairo_output_stream_write_hex_string (surface->final_stream,
subset.data, subset.data_length);
"/sfnts [\n");
begin = 0;
end = 0;
for (i = 0; i < subset.num_string_offsets; i++) {
end = subset.string_offsets[i];
_cairo_output_stream_printf (surface->final_stream,"<");
_cairo_output_stream_write_hex_string (surface->final_stream,
subset.data + begin, end - begin);
_cairo_output_stream_printf (surface->final_stream,"00>\n");
begin = end;
}
if (subset.data_length > end) {
_cairo_output_stream_printf (surface->final_stream,"<");
_cairo_output_stream_write_hex_string (surface->final_stream,
subset.data + end, subset.data_length - end);
_cairo_output_stream_printf (surface->final_stream,"00>\n");
}
_cairo_output_stream_printf (surface->final_stream,
">] def\n"
"] def\n"
"FontName currentdict end definefont pop\n");
_cairo_truetype_subset_fini (&subset);

View file

@ -187,6 +187,8 @@ typedef struct _cairo_truetype_subset {
long ascent, descent;
char *data;
unsigned long data_length;
unsigned long *string_offsets;
unsigned long num_string_offsets;
} cairo_truetype_subset_t;
/**

View file

@ -1702,7 +1702,6 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
cairo_scaled_font_t *scaled_font)
{
cairo_status_t status;
cairo_glyph_t *dev_glyphs = (cairo_glyph_t*) glyphs;
cairo_scaled_font_t *dev_scaled_font = scaled_font;
cairo_pattern_union_t dev_source;
cairo_matrix_t font_matrix;
@ -1721,56 +1720,37 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
if (_cairo_surface_has_device_transform (surface) || font_matrix.x0 != 0.0 || font_matrix.y0 != 0.0)
if (_cairo_surface_has_device_transform (surface) &&
! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
{
int i;
cairo_font_options_t *font_options;
cairo_matrix_t dev_ctm;
dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
if (!dev_glyphs)
return CAIRO_STATUS_NO_MEMORY;
font_options = cairo_font_options_create ();
for (i = 0; i < num_glyphs; i++) {
dev_glyphs[i].index = glyphs[i].index;
dev_glyphs[i].x = glyphs[i].x + font_matrix.x0;
dev_glyphs[i].y = glyphs[i].y + font_matrix.y0;
cairo_matrix_transform_point (&surface->device_transform,
&dev_glyphs[i].x,
&dev_glyphs[i].y);
}
if (! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL)) {
cairo_font_options_t *font_options;
cairo_matrix_t dev_ctm;
font_options = cairo_font_options_create ();
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
cairo_scaled_font_get_font_options (scaled_font, font_options);
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
&font_matrix,
&dev_ctm,
font_options);
cairo_font_options_destroy (font_options);
}
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
cairo_scaled_font_get_font_options (scaled_font, font_options);
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
&font_matrix,
&dev_ctm,
font_options);
cairo_font_options_destroy (font_options);
}
if (surface->backend->show_glyphs) {
status = surface->backend->show_glyphs (surface, op, &dev_source.base,
dev_glyphs, num_glyphs,
glyphs, num_glyphs,
dev_scaled_font);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto FINISH;
}
status = _cairo_surface_fallback_show_glyphs (surface, op, &dev_source.base,
dev_glyphs, num_glyphs,
glyphs, num_glyphs,
dev_scaled_font);
FINISH:
if (dev_glyphs != glyphs)
free (dev_glyphs);
if (dev_scaled_font != scaled_font)
cairo_scaled_font_destroy (dev_scaled_font);

View file

@ -37,35 +37,10 @@
#include "cairoint.h"
#include "cairo-xcb.h"
#include "cairo-xcb-xrender.h"
#include <X11/XCB/xcb_renderutil.h>
#define AllPlanes ((unsigned long)~0L)
static XCBRenderPICTFORMAT
format_from_visual(XCBConnection *c, XCBVISUALID visual)
{
static const XCBRenderPICTFORMAT nil = { 0 };
XCBRenderQueryPictFormatsRep *r;
XCBRenderPICTSCREENIter si;
XCBRenderPICTDEPTHIter di;
XCBRenderPICTVISUALIter vi;
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
if(!r)
return nil;
for(si = XCBRenderQueryPictFormatsScreensIter(r); si.rem; XCBRenderPICTSCREENNext(&si))
for(di = XCBRenderPICTSCREENDepthsIter(si.data); di.rem; XCBRenderPICTDEPTHNext(&di))
for(vi = XCBRenderPICTDEPTHVisualsIter(di.data); vi.rem; XCBRenderPICTVISUALNext(&vi))
if(vi.data->visual.id == visual.id)
{
XCBRenderPICTFORMAT ret = vi.data->format;
free(r);
return ret;
}
return nil;
}
static cairo_content_t
_xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
{
@ -92,95 +67,6 @@ _xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
}
/* XXX: Why is this ridiculously complex compared to the equivalent
* function in cairo-xlib-surface.c */
static XCBRenderPICTFORMINFO
_format_from_cairo(XCBConnection *c, cairo_format_t fmt)
{
XCBRenderPICTFORMINFO ret = {{ 0 }};
struct tmpl_t {
XCBRenderDIRECTFORMAT direct;
CARD8 depth;
};
static const struct tmpl_t templates[] = {
/* CAIRO_FORMAT_ARGB32 */
{
{
16, 0xff,
8, 0xff,
0, 0xff,
24, 0xff
},
32
},
/* CAIRO_FORMAT_RGB24 */
{
{
16, 0xff,
8, 0xff,
0, 0xff,
0, 0x00
},
24
},
/* CAIRO_FORMAT_A8 */
{
{
0, 0x00,
0, 0x00,
0, 0x00,
0, 0xff
},
8
},
/* CAIRO_FORMAT_A1 */
{
{
0, 0x00,
0, 0x00,
0, 0x00,
0, 0x01
},
1
},
};
const struct tmpl_t *tmpl;
XCBRenderQueryPictFormatsRep *r;
XCBRenderPICTFORMINFOIter fi;
if(fmt < 0 || fmt >= (sizeof(templates) / sizeof(*templates)))
return ret;
tmpl = templates + fmt;
r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
if(!r)
return ret;
for(fi = XCBRenderQueryPictFormatsFormatsIter(r); fi.rem; XCBRenderPICTFORMINFONext(&fi))
{
const XCBRenderDIRECTFORMAT *t, *f;
if(fi.data->type != XCBRenderPictTypeDirect)
continue;
if(fi.data->depth != tmpl->depth)
continue;
t = &tmpl->direct;
f = &fi.data->direct;
if(t->red_mask && (t->red_mask != f->red_mask || t->red_shift != f->red_shift))
continue;
if(t->green_mask && (t->green_mask != f->green_mask || t->green_shift != f->green_shift))
continue;
if(t->blue_mask && (t->blue_mask != f->blue_mask || t->blue_shift != f->blue_shift))
continue;
if(t->alpha_mask && (t->alpha_mask != f->alpha_mask || t->alpha_shift != f->alpha_shift))
continue;
ret = *fi.data;
}
free(r);
return ret;
}
/*
* Instead of taking two round trips for each blending request,
* assume that if a particular drawable fails GetImage that it will
@ -209,6 +95,9 @@ typedef struct cairo_xcb_surface {
int height;
int depth;
XCBRECTANGLE *clip_rects;
int num_clip_rects;
XCBRenderPICTURE picture;
XCBRenderPICTFORMINFO format;
int has_format;
@ -265,7 +154,7 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
XCBDRAWABLE d;
cairo_xcb_surface_t *surface;
cairo_format_t format = _cairo_format_from_content (content);
XCBRenderPICTFORMINFO xrender_format = _format_from_cairo (dpy, format);
XCBRenderPICTFORMINFO *xrender_format;
/* As a good first approximation, if the display doesn't have COMPOSITE,
* we're better off using image surfaces for all temporary operations
@ -280,9 +169,11 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
width <= 0 ? 1 : width,
height <= 0 ? 1 : height);
xrender_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), format);
/* XXX: what to do if xrender_format is null? */
surface = (cairo_xcb_surface_t *)
cairo_xcb_surface_create_with_xrender_format (dpy, d, src->screen,
&xrender_format,
xrender_format,
width, height);
if (surface->base.status) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -307,6 +198,8 @@ _cairo_xcb_surface_finish (void *abstract_surface)
if (surface->gc.xid)
XCBFreeGC (surface->dpy, surface->gc);
free (surface->clip_rects);
surface->dpy = NULL;
return CAIRO_STATUS_SUCCESS;
@ -565,6 +458,26 @@ _get_image_surface (cairo_xcb_surface_t *surface,
return CAIRO_STATUS_NO_MEMORY;
}
static void
_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
{
if (surface->num_clip_rects)
XCBRenderSetPictureClipRectangles (surface->dpy, surface->picture,
0, 0,
surface->num_clip_rects,
surface->clip_rects);
}
static void
_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
{
if (surface->num_clip_rects)
XCBSetClipRectangles(surface->dpy, XCBClipOrderingYXSorted, surface->gc,
0, 0,
surface->num_clip_rects,
surface->clip_rects );
}
static void
_cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
{
@ -573,6 +486,7 @@ _cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
surface->gc = XCBGCONTEXTNew(surface->dpy);
XCBCreateGC (surface->dpy, surface->gc, surface->drawable, 0, 0);
_cairo_xcb_surface_set_gc_clip_rects(surface);
}
static cairo_status_t
@ -1000,7 +914,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
cairo_int_status_t status;
int render_reference_x, render_reference_y;
int render_src_x, render_src_y;
XCBRenderPICTFORMINFO render_format;
int cairo_format;
XCBRenderPICTFORMINFO *render_format;
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1025,30 +940,94 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1);
cairo_format = CAIRO_FORMAT_A1;
break;
default:
render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8);
cairo_format = CAIRO_FORMAT_A8;
break;
}
render_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dst->dpy), cairo_format);
/* XXX: what to do if render_format is null? */
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
/* XXX: _format_from_cairo is slow. should cache something. */
status = _cairo_xcb_surface_set_attributes (src, &attributes);
if (status == CAIRO_STATUS_SUCCESS)
XCBRenderTrapezoids (dst->dpy,
_render_operator (op),
src->picture, dst->picture,
render_format.id,
render_format->id,
render_src_x + attributes.x_offset,
render_src_y + attributes.y_offset,
num_traps, (XCBRenderTRAP *) traps);
num_traps, (XCBRenderTRAPEZOID *) traps);
_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)
{
cairo_xcb_surface_t *surface = abstract_surface;
if (surface->clip_rects) {
free (surface->clip_rects);
surface->clip_rects = NULL;
}
surface->num_clip_rects = 0;
if (region == NULL) {
if (surface->gc.xid) {
CARD32 mask = XCBGCClipMask;
CARD32 pa[] = { XCBNone };
XCBChangeGC (surface->dpy, surface->gc, mask, pa);
}
if (surface->has_format && surface->picture.xid) {
CARD32 mask = XCBRenderCPClipMask;
CARD32 pa[] = { XCBNone };
XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa);
}
} else {
pixman_box16_t *boxes;
XCBRECTANGLE *rects = NULL;
int n_boxes, i;
n_boxes = pixman_region_num_rects (region);
if (n_boxes > 0) {
rects = malloc (sizeof(XCBRECTANGLE) * n_boxes);
if (rects == NULL)
return CAIRO_STATUS_NO_MEMORY;
} else {
rects = NULL;
}
boxes = pixman_region_rects (region);
for (i = 0; i < n_boxes; i++) {
rects[i].x = boxes[i].x1;
rects[i].y = boxes[i].y1;
rects[i].width = boxes[i].x2 - boxes[i].x1;
rects[i].height = boxes[i].y2 - boxes[i].y1;
}
surface->clip_rects = rects;
surface->num_clip_rects = n_boxes;
if (surface->gc.xid)
_cairo_xcb_surface_set_gc_clip_rects (surface);
if (surface->picture.xid)
_cairo_xcb_surface_set_picture_clip_rects (surface);
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_xcb_surface_get_extents (void *abstract_surface,
cairo_rectangle_int16_t *rectangle)
@ -1078,7 +1057,7 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
_cairo_xcb_surface_composite_trapezoids,
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* _cairo_xcb_surface_set_clip_region */
_cairo_xcb_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_xcb_surface_get_extents,
NULL, /* old_show_glyphs */
@ -1103,26 +1082,6 @@ _cairo_surface_is_xcb (cairo_surface_t *surface)
return surface->backend == &cairo_xcb_surface_backend;
}
static void
query_render_version (XCBConnection *c, cairo_xcb_surface_t *surface)
{
XCBRenderQueryVersionRep *r;
surface->render_major = -1;
surface->render_minor = -1;
if (!XCBRenderInit(c))
return;
r = XCBRenderQueryVersionReply(c, XCBRenderQueryVersion(c, 0, 6), 0);
if (!r)
return;
surface->render_major = r->major_version;
surface->render_minor = r->minor_version;
free(r);
}
static cairo_surface_t *
_cairo_xcb_surface_create_internal (XCBConnection *dpy,
XCBDRAWABLE drawable,
@ -1134,6 +1093,7 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
int depth)
{
cairo_xcb_surface_t *surface;
const XCBRenderQueryVersionRep *r;
surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL) {
@ -1163,6 +1123,9 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
surface->height = height;
surface->depth = depth;
surface->clip_rects = NULL;
surface->num_clip_rects = 0;
if (format) {
surface->depth = format->depth;
} else if (visual) {
@ -1189,30 +1152,40 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
;
}
query_render_version(dpy, surface);
surface->render_major = -1;
surface->render_minor = -1;
r = XCBRenderUtilQueryVersion(dpy);
if (r) {
surface->render_major = r->major_version;
surface->render_minor = r->minor_version;
}
surface->picture.xid = 0;
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
{
XCBRenderPICTFORMAT pict_format = {0};
XCBRenderPICTFORMINFO format_info;
static const XCBRenderPICTFORMAT nil = { 0 };
const XCBRenderPICTFORMAT *pict_format = &nil;
surface->picture = XCBRenderPICTURENew(dpy);
if (!format) {
if (visual) {
pict_format = format_from_visual (dpy, visual->visual_id);
} else if (depth == 1) {
format_info = _format_from_cairo (dpy, CAIRO_FORMAT_A1);
pict_format = format_info.id;
}
XCBRenderCreatePicture (dpy, surface->picture, drawable,
pict_format, 0, NULL);
} else {
XCBRenderCreatePicture (dpy, surface->picture, drawable,
format->id, 0, NULL);
if (format) {
pict_format = &format->id;
} else if (visual) {
XCBRenderPICTVISUAL *pict_visual;
pict_visual = XCBRenderUtilFindVisualFormat (XCBRenderUtilQueryFormats (dpy), visual->visual_id);
if (pict_visual)
pict_format = &pict_visual->format;
} else if (depth == 1) {
XCBRenderPICTFORMINFO *format_info;
format_info = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), CAIRO_FORMAT_A1);
if (format_info)
pict_format = &format_info->id;
}
/* XXX: if pict_format is nil, should we still call CreatePicture? */
surface->picture = XCBRenderPICTURENew(dpy);
XCBRenderCreatePicture (dpy, surface->picture, drawable,
*pict_format, 0, NULL);
}
return (cairo_surface_t *) surface;

View file

@ -2674,12 +2674,13 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_surface_attributes_t attributes;
cairo_xlib_surface_t *src = NULL;
cairo_glyph_t *output_glyphs;
const cairo_glyph_t *glyphs_chunk;
int glyphs_remaining, chunk_size, max_chunk_size;
cairo_scaled_glyph_t *scaled_glyph;
cairo_xlib_surface_font_private_t *font_private;
int i;
int i, o;
unsigned long max_index = 0;
cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
@ -2723,6 +2724,13 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
(font_private != NULL && font_private->dpy != dst->dpy))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We make a copy of the glyphs so that we can elide any size-zero
* glyphs to workaround an X server bug, (present in at least Xorg
* 7.1 without EXA). */
output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
if (output_glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
/* After passing all those tests, we're now committed to rendering
* these glyphs or to fail trying. We first upload any glyphs to
* the X server that it doesn't have already, then we draw
@ -2781,7 +2789,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
goto BAIL;
/* Send all unsent glyphs to the server, and count the max of the glyph indices */
for (i = 0; i < num_glyphs; i++) {
for (i = 0, o = 0; i < num_glyphs; i++) {
if (glyphs[i].index > max_index)
max_index = glyphs[i].index;
status = _cairo_scaled_glyph_lookup (scaled_font,
@ -2790,11 +2798,18 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
&scaled_glyph);
if (status != CAIRO_STATUS_SUCCESS)
goto BAIL;
if (scaled_glyph->surface_private == NULL) {
_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
scaled_glyph->surface_private = (void *) 1;
/* Don't put any size-zero glyphs into output_glyphs to avoid
* an X server bug which stops rendering glyphs after the
* first size-zero glyph. */
if (scaled_glyph->surface->width && scaled_glyph->surface->height) {
output_glyphs[o++] = glyphs[i];
if (scaled_glyph->surface_private == NULL) {
_cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
scaled_glyph->surface_private = (void *) 1;
}
}
}
num_glyphs = o;
_cairo_xlib_surface_ensure_dst_picture (dst);
@ -2811,7 +2826,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
}
max_chunk_size /= sz_xGlyphElt;
for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
for (glyphs_remaining = num_glyphs, glyphs_chunk = output_glyphs;
glyphs_remaining;
glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
{
@ -2826,6 +2841,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
BAIL:
_cairo_scaled_font_thaw_cache (scaled_font);
free (output_glyphs);
if (src)
_cairo_pattern_release_surface (src_pattern, &src->base, &attributes);

View file

@ -928,10 +928,10 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
* #CAIRO_STATUS_INVALID_DASH.
**/
void
cairo_set_dash (cairo_t *cr,
double *dashes,
int num_dashes,
double offset)
cairo_set_dash (cairo_t *cr,
const double *dashes,
int num_dashes,
double offset)
{
if (cr->status)
return;

View file

@ -418,10 +418,10 @@ cairo_public void
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join);
cairo_public void
cairo_set_dash (cairo_t *cr,
double *dashes,
int num_dashes,
double offset);
cairo_set_dash (cairo_t *cr,
const double *dashes,
int num_dashes,
double offset);
cairo_public void
cairo_set_miter_limit (cairo_t *cr, double limit);

View file

@ -1162,7 +1162,7 @@ cairo_private cairo_line_join_t
_cairo_gstate_get_line_join (cairo_gstate_t *gstate);
cairo_private cairo_status_t
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset);
_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset);
cairo_private cairo_status_t
_cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit);

View file

@ -454,10 +454,10 @@ endif
EXTRA_PROGRAMS = $(TESTS) $(SUPPORT_PROGS)
# Emptying TARGET makes sure that user's environment variable doesn't
# affect tested targets in test suite. To limit tested targets, one
# has to set TARGETS=target,list on the make command line
TARGETS =
# Do a funny transition of CAIRO_TEST_TARGET through TARGETS such that
# one can limit tested targets both through CAIRO_TEST_TARGET env var
# and TARGETS make var on the command line.
TARGETS = $(CAIRO_TEST_TARGET)
TESTS_ENVIRONMENT = CAIRO_XFAIL_TESTS="$(XFAIL_TESTS)" CAIRO_TEST_TARGET="$(TARGETS)"