mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 22:18:29 +02:00
Merge branch 'master' of ssh+git://git.cairographics.org/git/cairo
This commit is contained in:
commit
c05dd48ac1
18 changed files with 331 additions and 450 deletions
3
INSTALL
3
INSTALL
|
|
@ -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
199
ROADMAP
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)"])
|
||||
])
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue