b=404092, upgrade cairo to 1.5.2-55
git-svn-id: svn://10.0.0.236/trunk@240123 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
603b1cf9e1
commit
5c869f2081
@ -7,8 +7,8 @@ http://www.cairographics.org/.
|
||||
|
||||
VERSIONS:
|
||||
|
||||
cairo (1.5.x - d8b0de01d67cdf73d8266a73f54ba1ac42fee3c9)
|
||||
pixman (0.9.x - 3be35594c99b7abd2af43b66349ca53bfa1462d6)
|
||||
cairo (1.5.x - 1.5.2-55-g39b8ddf)
|
||||
pixman (0.9.x - pixman-0.9.6-13-g4193b3c)
|
||||
glitz 0.5.2 (cvs - 2006-01-10)
|
||||
|
||||
***** NOTE FOR VISUAL C++ 6.0 *****
|
||||
@ -25,8 +25,4 @@ win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
|
||||
|
||||
nonfatal-assertions.patch: Make assertions non-fatal
|
||||
|
||||
win32-glyph-metrics.patch: GetGlyphOutline only works on Truetype fonts,
|
||||
so for non-Truetype fonts, assume no left or right bearing and use the
|
||||
font ascent and descent for the glyph extents.
|
||||
|
||||
endian.patch: include cairo-platform.h for endian macros
|
||||
|
||||
@ -1,26 +1,99 @@
|
||||
Josh Aas <joshmoz@gmail.com> Memory leak fix for quartz backend
|
||||
Daniel Amelang <dan@amelang.net> Many (magic) floating-point optimizations
|
||||
Shawn T. Amundson <amundson@gtk.org> Build fix
|
||||
Olivier Andrieu <oliv__a@users.sourceforge.net> PNG backend
|
||||
Peter Dennis Bartok <peter@novonyx.com> Bug fix for clipping
|
||||
Dave Beckett <dajobe@debian.org> Build fixes, Debian packaging
|
||||
Christian Biesinger <cbiesinger@web.de> BeOS backend
|
||||
Billy Biggs <vektor@dumbterm.net> Pixman code merge. Optimization. Fixes for subtle rendering bugs.
|
||||
Hans Breuer <hans@breuer.org> win32 bug fixes, build fixes, and improvements
|
||||
Brian Cameron <brian.cameron@sun.com> Flag bug in Sun's X server
|
||||
Damien Carbery <damien.carbery@sun.com> Build fixes
|
||||
Andrew Chant <andrew.chant@utoronto.ca> Adding const where needed
|
||||
Steve Chaplin <stevech1097@yahoo.com.au> Bug fixes for PNG reading
|
||||
Tomasz Cholewo <cholewo@ieee-cis.org> Bug fixes
|
||||
Manu Cornet <manu@manucornet.net> SVG build fix
|
||||
Frederic Crozat <fcrozat@mandriva.com> Fix test suite for OPD platforms (IA64 or PPC64)
|
||||
Radek Doulík <rodo@novell.com> Bug report and test case
|
||||
John Ehresman <jpe@wingide.com> Build fixes for win32
|
||||
John Ellson <ellson@research.att.com> First font/glyph extents functions
|
||||
Michael Emmel <mike.emmel@gmail.com> DirectFB backend
|
||||
Miklós Erdélyi <erdelyim@gmail.com> Fix typo leading to a crash
|
||||
Behdad Esfahbod <behdad@behdad.org> Huge piles of bug fixes, improvements, and general maintenance
|
||||
Brian Ewins <Brian.Ewins@gmail.com> ATSUI maintenance (first success at making it really work)
|
||||
Bertram Felgenhauer <int-e@gmx.de> Fixes for subtle arithmetic errors
|
||||
Bdale Garbee <bdale@gag.com> Provided essential support for cairo achitecture sessions
|
||||
Jens Granseuer <jensgr@gmx.net> Fixes to generate proper compiler flags
|
||||
Laxmi Harikumar <laxmi.harikumar@digital.com> Build fix
|
||||
J. Ali Harlow <ali@avrc.city.ac.uk> win32 backend updates
|
||||
Mathias Hasselmann <mathias.hasselmann@gmx.de> Significant reduction of calls to malloc
|
||||
Richard Henderson <rth@twiddle.net> "slim" macros for better shared libraries
|
||||
James Henstridge <james@daa.com.au> Build fixes related to freetype
|
||||
Graydon Hoare <graydon@redhat.com> Support for non-render X server, first real text support
|
||||
Thomas Hunger <info@teh-web.de> Initial version of cairo_in_stroke/fill
|
||||
Kristian Høgsberg <krh@redhat.com> PDF backend
|
||||
Kristian Høgsberg <krh@redhat.com> PDF backend, PS backend with meta-surfaces
|
||||
Amaury Jacquot <sxpert@esitcom.org> Documentation review, appplication testing
|
||||
Adrian Johnson <ajohnson@redneon.com> PDF backend improvement
|
||||
Michael Johnson <ahze@ahze.net> Bug fix for pre-C99 compilers
|
||||
Jonathon Jongsma <jonathon.jongsma@gmail.com> Fix documentation typos
|
||||
Øyvind Kolås <pippin@freedesktop.org> Bug fixes. Better default values.
|
||||
Martin Kretzschmar <martink@gnome.org> Arithmetic fix for 64-bit architectures
|
||||
Mathieu Lacage <Mathieu.Lacage@sophia.inria.fr> several bug/typo fixes
|
||||
Dominic Lachowicz <domlachowicz@gmail.com> PDF conformance fix, fix image surface to zero out contents
|
||||
Alexander Larsson <alexl@redhat.com> Profiling and performance fixes.
|
||||
Tor Lillqvist <tml@novell.com> win32 build fixes, build scripts
|
||||
Jinghua Luo <sunmoon1997@gmail.com> Add bitmap glyph transformation, many freetype and glitz fixes
|
||||
Luke-Jr <luke-jr@utopios.org> Build fix for cross-compiling
|
||||
Kjartan Maraas <kmaraas@gnome.org> Several fixes for sparse, lots of debug help for multi-thread bugs
|
||||
Jordi Mas <jordi@ximian.com> Bug fix for cairo_show_text
|
||||
Nicholas Miell <nmiell@gmail.com> Fixes for linking bugs on AMD64
|
||||
Eugeniy Meshcheryakov <eugen@debian.org> PS/PDF font subsetting improvements
|
||||
Zakharov Mikhail <zmey20000@yahoo.com> Build fix for HP-UX
|
||||
Christopher (Monty) Montgomery <xiphmont@gmail.com> Performnace fix (subimage_copy), multi-thread testing
|
||||
Tim Mooney <enchanter@users.sourceforge.net> Fix test suite to compile with Solaris compiler
|
||||
Jeff Muizelaar <jeff@infidigm.net> Patient, painful, pixman code merge. Many fixes for intricacies of dashing.
|
||||
Yevgen Muntyan <muntyan@tamu.edu> win32 build fix
|
||||
Declan Naughton <piratepenguin@gmail.com> Fix documentation typos
|
||||
Peter Nilsson <c99pnn@cs.umu.se> Glitz backend
|
||||
Henning Noren <henning.noren.402@student.lu.se> Fix memory leak
|
||||
Geoff Norton <gnorton@customerdna.com> Build fixes
|
||||
Robert O'Callahan <rocallahan@novell.com> Const-correctness fixes, several new API functions for completeness (and to help mozilla)
|
||||
Ian Osgood <iano@quirkster.com> XCB backend maintenance
|
||||
Benjamin Otte <in7y118@public.uni-hamburg.de> Refinements to cairo/perf timing
|
||||
Mike Owens <etc@filespanker.com> Bug fixes
|
||||
Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr> SVG backend
|
||||
Keith Packard <keithp@keithp.com> Original concept, polygon tessellation, dashing, font metrics rewrite
|
||||
Stuart Parmenter <pavlov@pavlov.net> Original GDI+ backend, win32 fixes
|
||||
Alfred Peng <alfred.peng@sun.com> Fixes for Sun compilers and for a memory leak
|
||||
Christof Petig <christof@petig-baender.de> Build fixes related to freetype
|
||||
Joonas Pihlaja <jpihlaja@cc.helsinki.fi> Huge improvements to the tessellator performance
|
||||
Mart Raudsepp <leio@dustbite.net> Build fixes
|
||||
David Reveman <davidr@novell.com> New pattern API, glitz backend
|
||||
Calum Robinson <calumr@mac.com> Quartz backend
|
||||
Pavel Roskin <proski@gnu.org> Several cleanups to eliminate warnings
|
||||
Tim Rowley <tim.rowley@gmail.com> Quartz/ATSUI fixes, X server workarounds, win32 glyph path support, test case to expose gradient regression
|
||||
Soeren Sandmann <sandmann@daimi.au.dk> Lots of MMX love for pixman compositing
|
||||
Torsten Schönfeld <kaffeetisch@gmx.de> Build fixes
|
||||
Jamey Sharp <jamey@minilop.net> Surface/font backend virtualization, XCB backend
|
||||
Jason Dorje Short <jdorje@users.sf.net> Build fixes and bug fixes
|
||||
Jeff Smith <whydoubt@yahoo.com> Fixes for intricacies of stroking code
|
||||
Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix
|
||||
Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc
|
||||
Owen Taylor <otaylor@redhat.com> Font support rewrite
|
||||
Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option
|
||||
Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend
|
||||
Alp Toker <alp@atoker.com> Fix several code/comment typos
|
||||
Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes
|
||||
David Turner <david@freetype.org> Optimize gradient calculations
|
||||
Kalle Vahlman <kalle.vahlman@gmail.com> Allow perf reports to be compared across different platforms
|
||||
Sasha Vasko <sasha@aftercode.net> Build fix to compile without xlib backend
|
||||
Vladimir Vukicevic <vladimir@pobox.com> Bug fix for clipping
|
||||
Vladimir Vukicevic <vladimir@pobox.com> Quartz backend rewrite, win32/quartz maintenance
|
||||
Jonathan Watt <jwatt@jwatt.org> win32 fixes
|
||||
Peter Weilbacher <pmw@avila.aip.de> OS/2 backend
|
||||
Dan Williams <dcbw@redhat.com> Implemnt MMX function to help OLPC
|
||||
Chris Wilson <chris@chris-wilson.co.uk> Large-scale robustness improvements, (warn_unsed_result and malloc failure injection)
|
||||
Carl Worth <cworth@isi.edu> Original library, support for paths, images
|
||||
Richard D. Worth <richard@theworths.org> Build fixes for cygwin
|
||||
Kent Worsnop <kworsnop@accesswave.ca> Fix PDF dashing bug
|
||||
Dave Yeo <daveryeo@telus.net> Build fix for win32
|
||||
|
||||
(please let us know if we have missed anyone)
|
||||
|
||||
@ -1,9 +1,128 @@
|
||||
This package uses automake, in order to generate the Makefiles use:
|
||||
Quick-start build instructions
|
||||
------------------------------
|
||||
1) Configure the package:
|
||||
|
||||
$ autogen.sh
|
||||
./configure
|
||||
|
||||
After that, standard build procedures apply:
|
||||
2) Compile it:
|
||||
|
||||
$ make
|
||||
# make install
|
||||
make
|
||||
|
||||
3) Install it:
|
||||
|
||||
make install
|
||||
|
||||
This final step may require temporary root access (eg. with sudo) if
|
||||
you don't have write permission to the directory in which cairo will
|
||||
be installed.
|
||||
|
||||
NOTE: If you are working with source from git/cvs rather than from a tar
|
||||
file, then you should use ./autogen.sh in place of ./configure
|
||||
anywhere it is mentioned in these instructions.
|
||||
|
||||
More detailed build instructions
|
||||
--------------------------------
|
||||
|
||||
1) Configure the package
|
||||
|
||||
The first step in building cairo is to configure the package by
|
||||
running the configure script. The configure script attempts to
|
||||
automatically detect as much as possible about your system. So,
|
||||
you should primarily just accept its defaults by running:
|
||||
|
||||
./configure
|
||||
|
||||
The configure script does accept a large number of options for
|
||||
fine-tuning its behavior. See "./configure --help" for a complete
|
||||
list. The most commonly used options are discussed here.
|
||||
|
||||
--prefix=PREFIX
|
||||
|
||||
This option specifies the directory under which the software
|
||||
should be installed. By default configure will choose a
|
||||
directory such as /usr/local. If you would like to install
|
||||
cairo to some other location, pass the director to configure
|
||||
with the --prefix option. For example:
|
||||
|
||||
./configure --prefix=/opt/cairo
|
||||
|
||||
would install cairo into the /opt/cairo directory. You could
|
||||
also choose a prefix directory within your home directory if
|
||||
you don't have write access to any system-wide directory.
|
||||
|
||||
After installing into a custom prefix, you will need to set
|
||||
some environment variables to allow the software to be
|
||||
found. Assuming the /opt/cairo prefix and assuming you are
|
||||
using the bash shell, the following environment variables
|
||||
should be set:
|
||||
|
||||
PKG_CONFIG_PATH=/opt/cairo/lib/pkgconfig
|
||||
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-quartz
|
||||
--enable-atsui
|
||||
--enable-xcb
|
||||
--enable-glitz
|
||||
--enable-beos
|
||||
--enable-os2
|
||||
--enable-directfb
|
||||
|
||||
Some of cairo's backends are marked as experimental and will
|
||||
not be built by default. If you would like to build and
|
||||
experiment with these backends, you will need to pass one of
|
||||
the above options to the configure script. You may need to
|
||||
have certain libraries installed first as discussed in the
|
||||
dependencies section of the README file.
|
||||
|
||||
--disable-xlib
|
||||
--disable-win32
|
||||
--disable-png
|
||||
--disable-freetype
|
||||
--disable-ps
|
||||
--disable-pdf
|
||||
--disable-svg
|
||||
|
||||
Cairo's configure script detects the libraries needed to build
|
||||
each stable backend, and when it finds them, enables each
|
||||
backend. If you would like to override this detection and
|
||||
disable a backend, (even when it would be possible to build
|
||||
it), use one of the options above to disable the backend.
|
||||
|
||||
2) Compile the package:
|
||||
|
||||
This step is very simple. Just:
|
||||
|
||||
make
|
||||
|
||||
The Makefiles included with cairo are designed to work on as many
|
||||
different systems as possible.
|
||||
|
||||
When cairo is compiled, you can also run some automated tests of
|
||||
cairo with:
|
||||
|
||||
make check
|
||||
|
||||
NOTE: Some versions of X servers will cause the -xlib tests to
|
||||
report failures in make check even when cairo is working just
|
||||
fine. If you see failures in nothing but -xlib tests, please
|
||||
examine the corresponding -xlib-out.png images and compare them to
|
||||
the -ref.png reference images (the -xlib-diff.png images might also
|
||||
be useful). If the results seem "close enough" please do not report
|
||||
a bug against cairo as the "failures" you are seeing are just due
|
||||
to subtle variations in X server implementations.
|
||||
|
||||
3) Install the package:
|
||||
|
||||
The final step is to install the package with:
|
||||
|
||||
make install
|
||||
|
||||
If you are installing to a system-wide location you may need to
|
||||
temporarily acquite root access in order to perform this
|
||||
operation. A good way to do this is to use the sudo program:
|
||||
|
||||
sudo make install
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,60 +1,161 @@
|
||||
Cairo - Multi-platform 2D graphics library
|
||||
http://cairographics.org
|
||||
|
||||
Compiling
|
||||
---------
|
||||
See the INSTALL document for build instructions.
|
||||
What is cairo
|
||||
=============
|
||||
Cairo is a 2D graphics library with support for multiple output
|
||||
devices. Currently supported output targets include the X Window
|
||||
System, win32, and image buffers, as well as PDF, PostScript, and SVG
|
||||
file output. Experimental backends include OpenGL (through glitz),
|
||||
Quartz, XCB, BeOS, OS/2, and DirectFB.
|
||||
|
||||
Description
|
||||
-----------
|
||||
Cairo is a vector graphics library with cross-device output
|
||||
support. Currently supported output targets include the X Window
|
||||
System and in-memory image buffers. PostScript and PDF file output is
|
||||
planned. Cairo is designed to produce identical output on all output
|
||||
media while taking advantage of display hardware acceleration when
|
||||
available (eg. through the X Render Extension).
|
||||
Cairo is designed to produce consistent output on all output media
|
||||
while taking advantage of display hardware acceleration when available
|
||||
(for example, through the X Render Extension).
|
||||
|
||||
Cairo provides a stateful user-level API with capabilities similar to
|
||||
the PDF 1.4 imaging model. Cairo provides operations including
|
||||
stroking and filling Bezier cubic splines, transforming and
|
||||
compositing translucent images, and antialiased text rendering.
|
||||
The cairo API provides operations similar to the drawing operators of
|
||||
PostScript and PDF. Operations in cairo include stroking and filling
|
||||
cubic Bézier splines, transforming and compositing translucent images,
|
||||
and antialiased text rendering. All drawing operations can be
|
||||
transformed by any affine transformation (scale, rotation, shear,
|
||||
etc.).
|
||||
|
||||
Cairo was once named Xr, (or Xr/Xc), so if you came looking for that
|
||||
software, you've found it.
|
||||
Cairo has been designed to let you draw anything you want in a modern
|
||||
2D graphical user interface. At the same time, the cairo API has been
|
||||
designed to be as fun and easy to learn as possible. If you're not
|
||||
having fun while programming with cairo, then we have failed
|
||||
somewhere---let us know and we'll try to fix it next time around.
|
||||
|
||||
Cairo is free software and is available to be redistributed and/or
|
||||
modified under the terms of either the GNU Lesser General Public
|
||||
License (LGPL) version 2.1 or the Mozilla Public License (MPL) version
|
||||
1.1.
|
||||
|
||||
Where to get more information about cairo
|
||||
=========================================
|
||||
The primary source of information about cairo is:
|
||||
|
||||
http://cairographics.org/
|
||||
|
||||
The latest releases of cairo can be found at:
|
||||
|
||||
http://cairographics.org/releases
|
||||
|
||||
Snapshots of in-development versions of cairo:
|
||||
|
||||
http://cairographics.org/snapshots
|
||||
|
||||
The programming manual for using cairo:
|
||||
|
||||
http://cairographics.org/manual
|
||||
|
||||
Mailing lists for contacting cairo users and developers:
|
||||
|
||||
http://cairographics.org/lists
|
||||
|
||||
Answers to some frequently asked questions about cairo:
|
||||
|
||||
http://cairographics.org/FAQ
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
Cairo currently requires the following supporting libraries:
|
||||
============
|
||||
The set of libraries needed to compile cairo depends on which backends
|
||||
are enabled when cairo is configured. Here are the dependencies for
|
||||
each backend:
|
||||
|
||||
libpixman
|
||||
Xft2
|
||||
fontconfig
|
||||
freetype2
|
||||
Surface backends:
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
There's not much documentation yet apart from the cairo.h header
|
||||
file. We'll be correcting that shortly.
|
||||
image backend (required)
|
||||
------------------------
|
||||
pixman http://cairographics.org/releases
|
||||
or: git://git.cairographics.org/git/pixman
|
||||
|
||||
In the meantime, the cairo-demo module in CVS provides a few example
|
||||
programs using cairo. These may be helpful to a programmer just
|
||||
beginning with cairo. Also, familiarity with the PostScript imaging
|
||||
model will help in understanding cairo.
|
||||
glitz backend
|
||||
-------------
|
||||
glitz >= 0.4.4 http://freedesktop.org/Software/glitz
|
||||
|
||||
pdf backend
|
||||
-----------
|
||||
freetype >= 2.1.4 http://freetype.org
|
||||
zlib http://www.gzip.org/zlib
|
||||
|
||||
postscript backend
|
||||
------------------
|
||||
freetype >= 2.1.4 http://freetype.org
|
||||
zlib http://www.gzip.org/zlib
|
||||
|
||||
quartz backend
|
||||
--------------
|
||||
[*]
|
||||
|
||||
win32 backend
|
||||
-------------
|
||||
[*]
|
||||
|
||||
xcb backend
|
||||
-----------
|
||||
XCB http://xcb.freedesktop.org
|
||||
|
||||
xlib backend
|
||||
------------
|
||||
Xrender >= 0.6 http://freedesktop.org/Software/xlibs
|
||||
|
||||
beos backend
|
||||
------------
|
||||
No dependencies in itself other than an installed BeOS system, but cairo
|
||||
requires a font backend. See the freetype dependency list.
|
||||
|
||||
os2 backend
|
||||
-----------
|
||||
Cairo should run on any recent version of OS/2 or eComStation, but it
|
||||
requires a font backend. See the freetype dependency list. Ready to use
|
||||
packages and developer dependencies are available at Netlabs:
|
||||
ftp://ftp.netlabs.org/pub/cairo
|
||||
|
||||
Font backends:
|
||||
|
||||
freetype font backend
|
||||
---------------------
|
||||
freetype >= 2.1.4 http://freetype.org
|
||||
fontconfig http://fontconfig.org
|
||||
|
||||
win32 font backend
|
||||
------------------
|
||||
[*]
|
||||
|
||||
atsui font backend
|
||||
------------------
|
||||
[*]
|
||||
|
||||
[*] I don't know specifically what packages might need to be
|
||||
installed on a Mac OS X system to use the Quartz and ATSUI
|
||||
backends. As far as win32, the situation is rather complex:
|
||||
|
||||
The Win32 backend should work on Windows 2000 and newer
|
||||
(excluding Windows Me.) Most testing has been done on
|
||||
Windows XP. While some portions of the code have been
|
||||
adapted to work on older versions of Windows, considerable
|
||||
work still needs to be done to get cairo running in these
|
||||
environments.
|
||||
|
||||
Cairo can be compiled on Windows either with the GCC
|
||||
toolchain (see http://www.mingw.org) or with Microsoft
|
||||
Visual C++. Makefiles or project files for compiling with
|
||||
MSVC are however not provided as of this release. We have
|
||||
received reports that MSVC 6.0 compiles parts of cairo
|
||||
incorrectly, (leading to incorrect color). MSVC 7.0 is
|
||||
known to work.
|
||||
|
||||
Compiling
|
||||
=========
|
||||
See the INSTALL document for build instructions.
|
||||
|
||||
History
|
||||
-------
|
||||
=======
|
||||
Cairo was originally developed by Carl Worth <cworth@cworth.org> and
|
||||
Keith Packard <keithp@keithp.com>. Many thanks are due to Lyle Ramshaw
|
||||
without whose patient help our ignorance would be much more apparent.
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
If you have trouble with cairo or you have some ideas for how it could be
|
||||
improved, please feel free to send a message to cairo@cairographics.org
|
||||
|
||||
Cairo is still under active development and all discussion happens on
|
||||
that list. So if you want to lurk or, (even better), take part in the
|
||||
development, take a look. Subscription information and archives are
|
||||
available:
|
||||
|
||||
http://cairographics.org/cgi-bin/mailman/listinfo/cairo
|
||||
Since the original development, many more people have contributed to
|
||||
cairo. See the AUTHORS files for as complete a list as we've been able
|
||||
to compile so far.
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
Changes that are expected to impact the public API
|
||||
==================================================
|
||||
|
||||
Patch submitted to mailing list?
|
||||
/ Documentation included in patch?
|
||||
|/ Review of patch completed?
|
||||
||/ Test case included?
|
||||
|||/ Committed.
|
||||
||||/
|
||||
Backwards compatible (API additions only)
|
||||
-----------------------------------------
|
||||
cairo_begin_group, cairo_end_group, cairo_get_group
|
||||
PDR C cairo_surface_mark_dirty (see below for details)
|
||||
PDRTC Add support for non-antialiased rendering + API
|
||||
Add CAIRO_FILL_RULE_INVERSE_WINDING and CAIRO_FILL_RULE_INVERSE_EVEN_ODD
|
||||
Add cairo_text_glyphs (see below for details)
|
||||
Add support for programmatic patterns, (ie. arbitrary gradients)
|
||||
P Add cairo_arc_to.
|
||||
Add support for custom caps (see below for details)
|
||||
Add support for getting at image data from image surface
|
||||
Add CAIRO_STATUS_DESTROYED
|
||||
Add cairo_finish
|
||||
|
||||
Backwards incompatible (API deletions or changes)
|
||||
-------------------------------------------------
|
||||
PDR C cairo_surface_finish, cairo_surface_flush
|
||||
PDR C A hidden offset for the xlib backend
|
||||
PDR C Consistent error handling for all objects
|
||||
PDRTC Split cairo_format_t (see below for details)
|
||||
P---C Remove cairo_status_string in favor of cairo_status_to_string
|
||||
|
||||
Details on some of the above changes
|
||||
------------------------------------
|
||||
* cairo_text_glyphs:
|
||||
|
||||
It would function as a sort of bridge between the toy and the
|
||||
real text APIs:
|
||||
|
||||
> void
|
||||
> cairo_text_glyphs (cairo_t *cr, const unsigned char *utf8,
|
||||
> cairo_glyph_t *glyphs, int *num_glyphs);
|
||||
>
|
||||
> with num_glyphs as an input-output parameter. The behavior of this
|
||||
> function would be such that calling:
|
||||
>
|
||||
> cairo_text_glyphs (cr, string, glyphs, &num_glyphs);
|
||||
> cairo_show_glyphs (cr, glyphs, num_glyphs);
|
||||
>
|
||||
> would be equivalent too:
|
||||
>
|
||||
> cairo_show_text (cr, string);
|
||||
>
|
||||
> as long as the original size of glyphs/num_glyphs was large
|
||||
> enough.
|
||||
|
||||
* support for custom caps:
|
||||
|
||||
It would be nice if the user had a mechanism to reliably draw custom
|
||||
caps. One approach here would be to provide the coordinates of the
|
||||
butt cap faces so that the user can append seamless caps to the
|
||||
current path. We may also need to provide the coordinates of the
|
||||
faces of every dash as well.
|
||||
|
||||
Changes that do not affect the public API
|
||||
=========================================
|
||||
* Fix clipping to work for all operators. The equation we have come up
|
||||
with is:
|
||||
|
||||
((src Op dest) In clip) Add (dest Out clip)
|
||||
|
||||
* Change stroke code to go through one giant polygon. This will fix
|
||||
problems with stroking self-intersecting paths.
|
||||
|
||||
* Fix the intersection problem, (see reference to Hobby's paper
|
||||
mentioned in cairo_traps.c).
|
||||
|
||||
* Implement dashing for cairo_curve_to.
|
||||
|
||||
* Stroking closed, degenerate paths should still draw caps. Round
|
||||
caps are easy; square should probably draw an axis-aligned square.
|
||||
|
||||
* Should add geometry pruning as appropriate.
|
||||
|
||||
* Verification, profiling, optimization.
|
||||
|
||||
centi_unfinished.svg may provide a good test case.
|
||||
@ -74,6 +74,7 @@ CSRCS = \
|
||||
cairo-analysis-surface.c \
|
||||
cairo-arc.c \
|
||||
cairo-array.c \
|
||||
cairo-atomic.c \
|
||||
cairo-bentley-ottmann.c \
|
||||
cairo-cache.c \
|
||||
cairo-clip.c \
|
||||
|
||||
@ -46,12 +46,16 @@ cairo_private cairo_region_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_analysis_surface_has_supported (cairo_surface_t *unsupported);
|
||||
_cairo_analysis_surface_has_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);
|
||||
_cairo_analysis_surface_has_unsupported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private void
|
||||
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *surface,
|
||||
cairo_box_t *bbox);
|
||||
|
||||
#endif /* CAIRO_ANALYSIS_SURFACE_H */
|
||||
|
||||
@ -48,12 +48,14 @@ typedef struct {
|
||||
|
||||
cairo_surface_t *target;
|
||||
|
||||
cairo_bool_t first_op;
|
||||
cairo_bool_t has_supported;
|
||||
cairo_bool_t has_unsupported;
|
||||
|
||||
cairo_region_t supported_region;
|
||||
cairo_region_t fallback_region;
|
||||
cairo_rectangle_int_t current_clip;
|
||||
cairo_box_t page_bbox;
|
||||
|
||||
} cairo_analysis_surface_t;
|
||||
|
||||
@ -74,7 +76,7 @@ _cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *
|
||||
analysis = _cairo_analysis_surface_create (surface->target,
|
||||
surface->width, surface->height);
|
||||
if (analysis == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_meta_surface_replay_analyze_meta_pattern (meta_surface, analysis);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
@ -90,10 +92,30 @@ _cairo_analysis_surface_add_operation (cairo_analysis_surface_t *surface,
|
||||
cairo_int_status_t backend_status)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_box_t bbox;
|
||||
|
||||
if (rect->width == 0 || rect->height == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
bbox.p1.x = _cairo_fixed_from_int (rect->x);
|
||||
bbox.p1.y = _cairo_fixed_from_int (rect->y);
|
||||
bbox.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
|
||||
bbox.p2.y = _cairo_fixed_from_int (rect->y + rect->height);
|
||||
|
||||
if (surface->first_op) {
|
||||
surface->first_op = FALSE;
|
||||
surface->page_bbox = bbox;
|
||||
} else {
|
||||
if (bbox.p1.x < surface->page_bbox.p1.x)
|
||||
surface->page_bbox.p1.x = bbox.p1.x;
|
||||
if (bbox.p1.y < surface->page_bbox.p1.y)
|
||||
surface->page_bbox.p1.y = bbox.p1.y;
|
||||
if (bbox.p2.x > surface->page_bbox.p2.x)
|
||||
surface->page_bbox.p2.x = bbox.p2.x;
|
||||
if (bbox.p2.y > surface->page_bbox.p2.y)
|
||||
surface->page_bbox.p2.y = bbox.p2.y;
|
||||
}
|
||||
|
||||
/* If the operation is completely enclosed within the fallback
|
||||
* region there is no benefit in emitting a native operation as
|
||||
* the fallback image will be painted on top.
|
||||
@ -557,6 +579,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
surface->height = height;
|
||||
|
||||
surface->target = target;
|
||||
surface->first_op = TRUE;
|
||||
surface->has_supported = FALSE;
|
||||
surface->has_unsupported = FALSE;
|
||||
_cairo_region_init (&surface->supported_region);
|
||||
@ -569,7 +592,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
|
||||
return &surface->base;
|
||||
FAIL:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -604,3 +627,12 @@ _cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
|
||||
|
||||
return surface->has_unsupported;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *abstract_surface,
|
||||
cairo_box_t *bbox)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||
|
||||
*bbox = surface->page_bbox;
|
||||
}
|
||||
|
||||
@ -133,17 +133,18 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
||||
if (array->elements == NULL) {
|
||||
array->elements = malloc (sizeof (char *));
|
||||
if (array->elements == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
*array->elements = NULL;
|
||||
}
|
||||
|
||||
array->size = new_size;
|
||||
new_elements = realloc (*array->elements,
|
||||
array->size * array->element_size);
|
||||
new_elements = _cairo_realloc_ab (*array->elements,
|
||||
array->size, array->element_size);
|
||||
|
||||
if (new_elements == NULL) {
|
||||
array->size = old_size;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
*array->elements = new_elements;
|
||||
|
||||
103
mozilla/gfx/cairo/cairo/src/cairo-atomic-private.h
Normal file
103
mozilla/gfx/cairo/cairo/src/cairo-atomic-private.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ATOMIC_PRIVATE_H
|
||||
#define CAIRO_ATOMIC_PRIVATE_H
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#define CAIRO_HAS_ATOMIC_OPS 1
|
||||
|
||||
#if CAIRO_HAS_INTEL_ATOMIC_PRIMITIVES
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
|
||||
|
||||
#else
|
||||
|
||||
# include "cairo-compiler-private.h"
|
||||
|
||||
# undef CAIRO_HAS_ATOMIC_OPS
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_inc (int *x);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x);
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CAIRO_ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
|
||||
# include "cairo-compiler-private.h"
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_get (int *x);
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_set (int *x, int value);
|
||||
|
||||
#else
|
||||
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_set(x, value) ((*x) = value)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define _cairo_status_set_error(status, err) do { \
|
||||
/* hide compiler warnings about cairo_status_t != int (gcc treats its as \
|
||||
* an unsigned integer instead, and about ignoring the return value. */ \
|
||||
int ret__ = _cairo_atomic_int_cmpxchg ((int *) status, CAIRO_STATUS_SUCCESS, err); \
|
||||
(void) ret__; \
|
||||
} while (0)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
96
mozilla/gfx/cairo/cairo/src/cairo-atomic.c
Normal file
96
mozilla/gfx/cairo/cairo/src/cairo-atomic.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-atomic-private.h"
|
||||
#include "cairo-mutex-private.h"
|
||||
|
||||
#ifndef CAIRO_HAS_ATOMIC_OPS
|
||||
void
|
||||
_cairo_atomic_int_inc (int *x)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x += 1;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x)
|
||||
{
|
||||
cairo_bool_t ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = --*x == 0;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
if (ret == oldv)
|
||||
*x = newv;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
int
|
||||
_cairo_atomic_int_get (int *x)
|
||||
{
|
||||
int ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_atomic_int_set (int *x, int value)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x = value;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
#endif
|
||||
@ -40,12 +40,6 @@
|
||||
#include "cairo-atsui.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
/* 10.5 SDK includes a funky new definition of FloatToFixed, so reset to old-style definition */
|
||||
#ifdef FloatToFixed
|
||||
#undef FloatToFixed
|
||||
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
|
||||
* here so we can use older SDKs.
|
||||
@ -69,6 +63,9 @@
|
||||
/* Public in 10.4, present in 10.3.9 */
|
||||
CG_EXTERN CGRect CGRectApplyAffineTransform (CGRect, CGAffineTransform);
|
||||
|
||||
/* Error code for path callbacks */
|
||||
static OSStatus CAIRO_CG_PATH_ERROR = 1001;
|
||||
|
||||
typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
|
||||
typedef struct _cairo_atsui_font cairo_atsui_font_t;
|
||||
typedef struct _cairo_atsui_scaled_path cairo_atsui_scaled_path_t;
|
||||
@ -90,7 +87,6 @@ struct _cairo_atsui_font {
|
||||
|
||||
Fixed size;
|
||||
CGAffineTransform font_matrix;
|
||||
CGFontRef cgfref;
|
||||
};
|
||||
|
||||
struct _cairo_atsui_font_face {
|
||||
@ -115,6 +111,7 @@ _cairo_atsui_font_face_scaled_font_create (void *abstract_face,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_atsui_font_face_t *font_face = abstract_face;
|
||||
OSStatus err;
|
||||
ATSUAttributeTag styleTags[] = { kATSUFontTag };
|
||||
@ -123,11 +120,22 @@ _cairo_atsui_font_face_scaled_font_create (void *abstract_face,
|
||||
ATSUStyle style;
|
||||
|
||||
err = ATSUCreateStyle (&style);
|
||||
if (err != noErr)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
|
||||
styleTags, styleSizes, styleValues);
|
||||
if (err != noErr) {
|
||||
ATSUDisposeStyle (style);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
return _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
|
||||
status = _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
|
||||
font_matrix, ctm, options, font);
|
||||
if (status)
|
||||
ATSUDisposeStyle (style);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
|
||||
@ -167,30 +175,35 @@ cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
|
||||
return &font_face->base;
|
||||
}
|
||||
|
||||
static ATSUStyle
|
||||
static OSStatus
|
||||
CreateSizedCopyOfStyle(ATSUStyle inStyle,
|
||||
const Fixed *theSize,
|
||||
const CGAffineTransform *theTransform)
|
||||
const CGAffineTransform *theTransform,
|
||||
ATSUStyle *style)
|
||||
{
|
||||
ATSUStyle style;
|
||||
OSStatus err;
|
||||
const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag,
|
||||
kATSUFontMatrixTag };
|
||||
kATSUFontMatrixTag };
|
||||
const ByteCount theFontStyleSizes[] = { sizeof(Fixed),
|
||||
sizeof(CGAffineTransform) };
|
||||
sizeof(CGAffineTransform) };
|
||||
ATSUAttributeValuePtr theFontStyleValues[] = { (Fixed *)theSize,
|
||||
(CGAffineTransform *)theTransform };
|
||||
(CGAffineTransform *)theTransform };
|
||||
|
||||
err = ATSUCreateAndCopyStyle(inStyle, &style);
|
||||
err = ATSUCreateAndCopyStyle (inStyle, style);
|
||||
if (err != noErr)
|
||||
return err;
|
||||
|
||||
err = ATSUSetAttributes(style,
|
||||
err = ATSUSetAttributes(*style,
|
||||
sizeof(theFontStyleTags) /
|
||||
sizeof(ATSUAttributeTag), theFontStyleTags,
|
||||
theFontStyleSizes, theFontStyleValues);
|
||||
if (err != noErr)
|
||||
ATSUDisposeStyle (*style);
|
||||
|
||||
return style;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
|
||||
{
|
||||
@ -208,7 +221,7 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
|
||||
|
||||
extents.ascent = metrics.ascent;
|
||||
extents.descent = -metrics.descent;
|
||||
extents.height = metrics.capHeight;
|
||||
extents.height = extents.ascent + extents.descent + metrics.leading;
|
||||
extents.max_x_advance = metrics.maxAdvanceWidth;
|
||||
|
||||
/* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
|
||||
@ -220,7 +233,7 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -240,7 +253,7 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
||||
|
||||
font = malloc(sizeof(cairo_atsui_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_scaled_font_init (&font->base,
|
||||
font_face, font_matrix, ctm, options,
|
||||
@ -257,7 +270,12 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
||||
0., 0.);
|
||||
font->size = FloatToFixed (xscale);
|
||||
|
||||
font->style = CreateSizedCopyOfStyle (style, &font->size, &font->font_matrix);
|
||||
err = CreateSizedCopyOfStyle (style, &font->size, &font->font_matrix, &font->style);
|
||||
if (err != noErr) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
{
|
||||
Fixed theSize = FloatToFixed(1.0);
|
||||
@ -270,7 +288,7 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
||||
sizeof(ATSUAttributeTag), theFontStyleTags,
|
||||
theFontStyleSizes, theFontStyleValues);
|
||||
if (err != noErr) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
@ -282,11 +300,14 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
||||
|
||||
status = _cairo_atsui_font_set_metrics (font);
|
||||
|
||||
font->cgfref = NULL;
|
||||
|
||||
FAIL:
|
||||
if (status) {
|
||||
cairo_scaled_font_destroy (&font->base);
|
||||
if (font) {
|
||||
if (font->style)
|
||||
ATSUDisposeStyle(font->style);
|
||||
free (font);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -300,6 +321,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_status_t status;
|
||||
ATSUStyle style;
|
||||
ATSUFontID fontID;
|
||||
OSStatus err;
|
||||
@ -308,6 +330,9 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
||||
const char *full_name;
|
||||
|
||||
err = ATSUCreateStyle(&style);
|
||||
if (err != noErr) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
switch (toy_face->weight) {
|
||||
case CAIRO_FONT_WEIGHT_BOLD:
|
||||
@ -381,6 +406,10 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
||||
kFontNoPlatformCode,
|
||||
kFontRomanScript,
|
||||
kFontNoLanguageCode, &fontID);
|
||||
if (err != noErr) {
|
||||
ATSUDisposeStyle (style);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,10 +422,18 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
||||
|
||||
err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
|
||||
styleTags, styleSizes, styleValues);
|
||||
if (err != noErr) {
|
||||
ATSUDisposeStyle (style);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
|
||||
status = _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
|
||||
font_matrix, ctm, options, font_out);
|
||||
if (status)
|
||||
ATSUDisposeStyle (style);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -411,9 +448,6 @@ _cairo_atsui_font_fini(void *abstract_font)
|
||||
ATSUDisposeStyle(font->style);
|
||||
if (font->unscaled_style)
|
||||
ATSUDisposeStyle(font->unscaled_style);
|
||||
if (font->cgfref)
|
||||
CGFontRelease(font->cgfref);
|
||||
|
||||
}
|
||||
|
||||
static GlyphID
|
||||
@ -448,7 +482,7 @@ _cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
|
||||
1, &theGlyph, 0, false,
|
||||
false, &metricsH);
|
||||
if (err != noErr)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* Scale down to font units.*/
|
||||
_cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
|
||||
@ -474,15 +508,21 @@ static OSStatus
|
||||
_move_to (const Float32Point *point,
|
||||
void *callback_data)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_atsui_scaled_path_t *scaled_path = callback_data;
|
||||
double x = point->x;
|
||||
double y = point->y;
|
||||
|
||||
cairo_matrix_transform_point (scaled_path->scale, &x, &y);
|
||||
_cairo_path_fixed_close_path (scaled_path->path);
|
||||
_cairo_path_fixed_move_to (scaled_path->path,
|
||||
status = _cairo_path_fixed_close_path (scaled_path->path);
|
||||
if (status)
|
||||
return CAIRO_CG_PATH_ERROR;
|
||||
|
||||
status = _cairo_path_fixed_move_to (scaled_path->path,
|
||||
_cairo_fixed_from_double (x),
|
||||
_cairo_fixed_from_double (y));
|
||||
if (status)
|
||||
return CAIRO_CG_PATH_ERROR;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@ -491,15 +531,18 @@ static OSStatus
|
||||
_line_to (const Float32Point *point,
|
||||
void *callback_data)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_atsui_scaled_path_t *scaled_path = callback_data;
|
||||
double x = point->x;
|
||||
double y = point->y;
|
||||
|
||||
cairo_matrix_transform_point (scaled_path->scale, &x, &y);
|
||||
|
||||
_cairo_path_fixed_line_to (scaled_path->path,
|
||||
status = _cairo_path_fixed_line_to (scaled_path->path,
|
||||
_cairo_fixed_from_double (x),
|
||||
_cairo_fixed_from_double (y));
|
||||
if (status)
|
||||
return CAIRO_CG_PATH_ERROR;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@ -510,6 +553,7 @@ _curve_to (const Float32Point *point1,
|
||||
const Float32Point *point3,
|
||||
void *callback_data)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_atsui_scaled_path_t *scaled_path = callback_data;
|
||||
double x1 = point1->x;
|
||||
double y1 = point1->y;
|
||||
@ -522,13 +566,15 @@ _curve_to (const Float32Point *point1,
|
||||
cairo_matrix_transform_point (scaled_path->scale, &x2, &y2);
|
||||
cairo_matrix_transform_point (scaled_path->scale, &x3, &y3);
|
||||
|
||||
_cairo_path_fixed_curve_to (scaled_path->path,
|
||||
status = _cairo_path_fixed_curve_to (scaled_path->path,
|
||||
_cairo_fixed_from_double (x1),
|
||||
_cairo_fixed_from_double (y1),
|
||||
_cairo_fixed_from_double (x2),
|
||||
_cairo_fixed_from_double (y2),
|
||||
_cairo_fixed_from_double (x3),
|
||||
_cairo_fixed_from_double (y3));
|
||||
if (status)
|
||||
return CAIRO_CG_PATH_ERROR;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@ -537,9 +583,12 @@ static OSStatus
|
||||
_close_path (void *callback_data)
|
||||
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_atsui_scaled_path_t *scaled_path = callback_data;
|
||||
|
||||
_cairo_path_fixed_close_path (scaled_path->path);
|
||||
status = _cairo_path_fixed_close_path (scaled_path->path);
|
||||
if (status)
|
||||
return CAIRO_CG_PATH_ERROR;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@ -562,7 +611,7 @@ _cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
|
||||
|
||||
scaled_path.path = _cairo_path_fixed_create ();
|
||||
if (!scaled_path.path)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (theGlyph == kATSDeletedGlyphcode) {
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base,
|
||||
@ -595,6 +644,10 @@ _cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
|
||||
lineProc,
|
||||
curveProc,
|
||||
closePathProc, (void *)&scaled_path, &err);
|
||||
if (err != noErr) {
|
||||
_cairo_path_fixed_destroy (scaled_path.path);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base,
|
||||
scaled_path.path);
|
||||
@ -658,6 +711,10 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
|
||||
err = ATSUGlyphGetScreenMetrics (scaled_font->style,
|
||||
1, &theGlyph, 0, false,
|
||||
false, &metricsH);
|
||||
if (err != noErr) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
left = metricsH.sideBearing.x - 1.0;
|
||||
width = metricsH.deviceAdvance.x
|
||||
- metricsH.sideBearing.x
|
||||
@ -715,7 +772,7 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
|
||||
|
||||
if (!drawingContext) {
|
||||
cairo_surface_destroy ((cairo_surface_t *)surface);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
|
||||
@ -803,29 +860,45 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
|
||||
|
||||
status = _cairo_utf8_to_utf16 ((unsigned char *)utf8, -1, &utf16, &n16);
|
||||
if (status)
|
||||
return status;
|
||||
goto BAIL3;
|
||||
|
||||
err = ATSUCreateTextLayout(&textLayout);
|
||||
if (err != noErr) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL3;
|
||||
}
|
||||
|
||||
err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
|
||||
if (err != noErr) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
}
|
||||
|
||||
/* Set the style for all of the text */
|
||||
err = ATSUSetRunStyle(textLayout,
|
||||
font->style, kATSUFromTextBeginning, kATSUToTextEnd);
|
||||
if (err != noErr) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
}
|
||||
|
||||
err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout,
|
||||
0,
|
||||
kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
||||
(void *)&layoutRecords,
|
||||
&glyphCount);
|
||||
if (err != noErr) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
}
|
||||
|
||||
*num_glyphs = glyphCount - 1;
|
||||
*glyphs =
|
||||
(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (*glyphs == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL1;
|
||||
}
|
||||
|
||||
_cairo_matrix_compute_scale_factors (&font->base.ctm, &xscale, &yscale, 1);
|
||||
device_to_user_scale =
|
||||
CGAffineTransformInvert (CGAffineTransformMake (xscale, 0,
|
||||
@ -841,14 +914,17 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
|
||||
(*glyphs)[i].y = y;
|
||||
}
|
||||
|
||||
free (utf16);
|
||||
|
||||
BAIL1:
|
||||
/* TODO ignored return value. Is there anything we should do? */
|
||||
ATSUDirectReleaseLayoutDataArrayPtr(NULL,
|
||||
kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
|
||||
(void *) &layoutRecords);
|
||||
BAIL2:
|
||||
ATSUDisposeTextLayout(textLayout);
|
||||
BAIL3:
|
||||
free (utf16);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
ATSUStyle
|
||||
@ -867,19 +943,6 @@ _cairo_atsui_scaled_font_get_atsu_font_id (cairo_scaled_font_t *sfont)
|
||||
return afont->fontID;
|
||||
}
|
||||
|
||||
CGFontRef
|
||||
_cairo_atsui_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont)
|
||||
{
|
||||
cairo_atsui_font_t *afont = (cairo_atsui_font_t *) sfont;
|
||||
|
||||
if (!afont->cgfref) {
|
||||
ATSFontRef atsfref = FMGetATSFontRefFromFont (afont->fontID);
|
||||
afont->cgfref = CGFontCreateWithPlatformFont (&atsfref);
|
||||
}
|
||||
return afont->cgfref;
|
||||
}
|
||||
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_atsui_load_truetype_table (void *abstract_font,
|
||||
unsigned long tag,
|
||||
|
||||
@ -114,8 +114,10 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
|
||||
cairo_base85_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_base85_stream_t));
|
||||
if (stream == NULL)
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base,
|
||||
_cairo_base85_stream_write,
|
||||
|
||||
@ -701,7 +701,7 @@ _cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue,
|
||||
/* Don't insert if there's already an equivalent intersection event in the queue. */
|
||||
if (_cairo_skip_list_insert (&queue->intersection_queue, event,
|
||||
event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -756,7 +756,7 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue,
|
||||
* elt? */
|
||||
events = _cairo_malloc_ab (num_events, sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*));
|
||||
if (events == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
|
||||
event_queue->startstop_events = events;
|
||||
@ -859,7 +859,7 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line,
|
||||
sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
|
||||
1 /* unique inserts*/);
|
||||
if (sweep_line_elt == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
next_elt = sweep_line_elt->elt.next[0];
|
||||
if (next_elt)
|
||||
@ -1147,7 +1147,7 @@ _cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *edge,
|
||||
if (edge->next) {
|
||||
trap = edge->deferred_trap = _cairo_freelist_alloc (&bo_traps->freelist);
|
||||
if (!edge->deferred_trap)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
trap->right = edge->next;
|
||||
trap->top = top;
|
||||
@ -1438,7 +1438,7 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
|
||||
} else {
|
||||
edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
|
||||
if (edges == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Figure out the bounding box of the input coordinates and
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#ifndef CAIRO_CACHE_PRIVATE_H
|
||||
#define CAIRO_CACHE_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
/**
|
||||
|
||||
@ -54,7 +54,7 @@ _cairo_cache_init (cairo_cache_t *cache,
|
||||
{
|
||||
cache->hash_table = _cairo_hash_table_create (keys_equal);
|
||||
if (cache->hash_table == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
cache->entry_destroy = entry_destroy;
|
||||
|
||||
@ -131,8 +131,10 @@ _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_t *cache;
|
||||
|
||||
cache = malloc (sizeof (cairo_cache_t));
|
||||
if (cache == NULL)
|
||||
if (cache == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = _cairo_cache_init (cache, keys_equal, entry_destroy, max_size);
|
||||
if (status) {
|
||||
|
||||
@ -385,15 +385,23 @@ cff_index_append_copy (cairo_array_t *index,
|
||||
unsigned int length)
|
||||
{
|
||||
cff_index_element_t element;
|
||||
cairo_status_t status;
|
||||
|
||||
element.length = length;
|
||||
element.is_copy = TRUE;
|
||||
element.data = malloc (element.length);
|
||||
if (element.data == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (element.data, object, element.length);
|
||||
|
||||
return _cairo_array_append (index, &element);
|
||||
status = _cairo_array_append (index, &element);
|
||||
if (status) {
|
||||
free (element.data);
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -419,10 +427,14 @@ _cairo_cff_dict_equal (const void *key_a, const void *key_b)
|
||||
return op_a->operator == op_b->operator;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
cff_dict_init (cairo_hash_table_t **dict)
|
||||
{
|
||||
*dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
|
||||
if (*dict == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -440,12 +452,16 @@ cff_dict_create_operator (int operator,
|
||||
cff_dict_operator_t *op;
|
||||
|
||||
op = malloc (sizeof (cff_dict_operator_t));
|
||||
if (op == NULL)
|
||||
if (op == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cairo_dict_init_key (op, operator);
|
||||
op->operand = malloc (operand_length);
|
||||
if (op->operand == NULL) {
|
||||
free (op);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
memcpy (op->operand, operand, operand_length);
|
||||
@ -480,7 +496,7 @@ cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
|
||||
_cairo_array_index (&operands, 0),
|
||||
_cairo_array_num_elements (&operands));
|
||||
if (op == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
status = _cairo_hash_table_insert (dict, &op->base);
|
||||
@ -544,8 +560,9 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
|
||||
{
|
||||
free (op->operand);
|
||||
op->operand = malloc (size);
|
||||
if (op->operand == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (op->operand == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (op->operand, operand, size);
|
||||
op->operand_length = size;
|
||||
}
|
||||
@ -553,7 +570,8 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
|
||||
{
|
||||
op = cff_dict_create_operator (operator, operand, size);
|
||||
if (op == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_hash_table_insert (dict, &op->base);
|
||||
if (status)
|
||||
return status;
|
||||
@ -690,6 +708,7 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
|
||||
unsigned char *ptr,
|
||||
int size)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
unsigned char buf[10];
|
||||
unsigned char *end_buf;
|
||||
int offset;
|
||||
@ -697,16 +716,23 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
|
||||
unsigned char *operand;
|
||||
unsigned char *p;
|
||||
|
||||
cff_dict_read (private_dict, ptr, size);
|
||||
status = cff_dict_read (private_dict, ptr, size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
|
||||
if (operand) {
|
||||
decode_integer (operand, &offset);
|
||||
p = ptr + offset;
|
||||
cff_index_read (local_sub_index, &p, font->data_end);
|
||||
status = cff_index_read (local_sub_index, &p, font->data_end);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Use maximum sized encoding to reserve space for later modification. */
|
||||
end_buf = encode_integer_max (buf, 0);
|
||||
cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
|
||||
status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -719,7 +745,7 @@ cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
|
||||
|
||||
font->fdselect = calloc (font->num_glyphs, sizeof (int));
|
||||
if (font->fdselect == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
type = *p++;
|
||||
if (type == 0)
|
||||
@ -767,28 +793,27 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
|
||||
|
||||
font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
|
||||
if (font->fd_dict == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
|
||||
if (font->fd_private_dict == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
|
||||
if (font->fd_local_sub_index == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < font->num_fontdicts; i++) {
|
||||
cff_dict_init (&font->fd_dict[i]);
|
||||
if (font->fd_dict[i] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = cff_dict_init (&font->fd_dict[i]);
|
||||
if (status)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
element = _cairo_array_index (&index, i);
|
||||
status = cff_dict_read (font->fd_dict[i], element->data, element->length);
|
||||
if (status)
|
||||
@ -801,11 +826,10 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
|
||||
}
|
||||
operand = decode_integer (operand, &size);
|
||||
decode_integer (operand, &offset);
|
||||
cff_dict_init (&font->fd_private_dict[i]);
|
||||
if (font->fd_private_dict[i] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = cff_dict_init (&font->fd_private_dict[i]);
|
||||
if (status)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cff_index_init (&font->fd_local_sub_index[i]);
|
||||
status = cairo_cff_font_read_private_dict (font,
|
||||
font->fd_private_dict[i],
|
||||
@ -828,7 +852,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
|
||||
fail:
|
||||
cff_index_fini (&index);
|
||||
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -870,28 +894,49 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
|
||||
if (font->is_cid) {
|
||||
operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
|
||||
decode_integer (operand, &offset);
|
||||
cairo_cff_font_read_fdselect (font, font->data + offset);
|
||||
status = cairo_cff_font_read_fdselect (font, font->data + offset);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
|
||||
decode_integer (operand, &offset);
|
||||
cairo_cff_font_read_cid_fontdict (font, font->data + offset);
|
||||
status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
|
||||
if (status)
|
||||
goto fail;
|
||||
} else {
|
||||
operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
|
||||
operand = decode_integer (operand, &size);
|
||||
decode_integer (operand, &offset);
|
||||
cairo_cff_font_read_private_dict (font,
|
||||
font->private_dict,
|
||||
&font->local_sub_index,
|
||||
font->data + offset,
|
||||
size);
|
||||
status = cairo_cff_font_read_private_dict (font,
|
||||
font->private_dict,
|
||||
&font->local_sub_index,
|
||||
font->data + offset,
|
||||
size);
|
||||
if (status)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Use maximum sized encoding to reserve space for later modification. */
|
||||
end_buf = encode_integer_max (buf, 0);
|
||||
cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
CHARSTRINGS_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
FDSELECT_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
FDARRAY_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
CHARSET_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
cff_dict_remove (font->top_dict, ENCODING_OP);
|
||||
cff_dict_remove (font->top_dict, PRIVATE_OP);
|
||||
@ -945,9 +990,10 @@ cairo_cff_font_read_font (cairo_cff_font_t *font)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char buf[30];
|
||||
unsigned char *p;
|
||||
int sid1, sid2;
|
||||
@ -955,22 +1001,32 @@ cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
|
||||
const char *ordering = "Identity";
|
||||
|
||||
sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
|
||||
cff_index_append_copy (&font->strings_subset_index,
|
||||
(unsigned char *)registry,
|
||||
strlen(registry));
|
||||
status = cff_index_append_copy (&font->strings_subset_index,
|
||||
(unsigned char *)registry,
|
||||
strlen(registry));
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
|
||||
cff_index_append_copy (&font->strings_subset_index,
|
||||
(unsigned char *)ordering,
|
||||
strlen(ordering));
|
||||
status = cff_index_append_copy (&font->strings_subset_index,
|
||||
(unsigned char *)ordering,
|
||||
strlen(ordering));
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
p = encode_integer (buf, sid1);
|
||||
p = encode_integer (p, sid2);
|
||||
p = encode_integer (p, 0);
|
||||
cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
|
||||
status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
|
||||
cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
|
||||
status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1000,7 +1056,9 @@ cairo_cff_font_subset_dict_string(cairo_cff_font_t *font,
|
||||
return status;
|
||||
|
||||
p = encode_integer (buf, sid);
|
||||
cff_dict_set_operands (dict, operator, buf, p - buf);
|
||||
status = cff_dict_set_operands (dict, operator, buf, p - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1063,19 +1121,19 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
|
||||
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
|
||||
sizeof (int));
|
||||
if (font->fdselect_subset == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
|
||||
if (font->fd_subset_map == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
|
||||
if (font->private_dict_offset == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
reverse_map = calloc (font->num_fontdicts, sizeof (int));
|
||||
if (reverse_map == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
for (i = 0; i < font->num_fontdicts; i++)
|
||||
reverse_map[i] = -1;
|
||||
@ -1100,21 +1158,27 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
|
||||
{
|
||||
unsigned char buf[100];
|
||||
unsigned char *end_buf;
|
||||
cairo_status_t status;
|
||||
|
||||
font->num_fontdicts = 1;
|
||||
font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
|
||||
if (font->fd_dict == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
cff_dict_init (&font->fd_dict[0]);
|
||||
if (cff_dict_init (&font->fd_dict[0])) {
|
||||
free (font->fd_dict);
|
||||
font->fd_dict = NULL;
|
||||
font->num_fontdicts = 0;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
font->fd_subset_map = malloc (sizeof (int));
|
||||
if (font->fd_subset_map == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->private_dict_offset = malloc (sizeof (int));
|
||||
if (font->private_dict_offset == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->fd_subset_map[0] = 0;
|
||||
font->num_subset_fontdicts = 1;
|
||||
@ -1123,7 +1187,9 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
|
||||
* space for any value later */
|
||||
end_buf = encode_integer_max (buf, 0);
|
||||
end_buf = encode_integer_max (end_buf, 0);
|
||||
cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
|
||||
status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1137,6 +1203,7 @@ cairo_cff_font_subset_strings (cairo_cff_font_t *font)
|
||||
status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (font->is_cid) {
|
||||
for (i = 0; i < font->num_subset_fontdicts; i++) {
|
||||
status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
|
||||
@ -1159,16 +1226,20 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
cairo_cff_font_set_ros_strings (font);
|
||||
status = cairo_cff_font_set_ros_strings (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_cff_font_subset_charstrings (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (font->is_cid)
|
||||
cairo_cff_font_subset_fontdict (font);
|
||||
status = cairo_cff_font_subset_fontdict (font);
|
||||
else
|
||||
cairo_cff_font_create_cid_fontdict (font);
|
||||
status = cairo_cff_font_create_cid_fontdict (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_cff_font_subset_strings (font);
|
||||
if (status)
|
||||
@ -1211,21 +1282,25 @@ cairo_cff_font_write_header (cairo_cff_font_t *font)
|
||||
static cairo_status_t
|
||||
cairo_cff_font_write_name (cairo_cff_font_t *font)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_array_t index;
|
||||
cairo_status_t status;
|
||||
|
||||
cff_index_init (&index);
|
||||
|
||||
status = cff_index_append_copy (&index,
|
||||
(unsigned char *) font->subset_font_name,
|
||||
strlen(font->subset_font_name));
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
|
||||
status = cff_index_write (&index, &font->output);
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
|
||||
FAIL:
|
||||
cff_index_fini (&index);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1428,6 +1503,7 @@ cairo_cff_font_write_private_dict (cairo_cff_font_t *font,
|
||||
status = cff_dict_write (private_dict, &font->output);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
|
||||
/* private entry has two operands - size and offset */
|
||||
buf_end = encode_integer_max (buf, size);
|
||||
@ -1476,7 +1552,7 @@ static cairo_status_t
|
||||
cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
|
||||
{
|
||||
unsigned int i;
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (font->is_cid) {
|
||||
for (i = 0; i < font->num_subset_fontdicts; i++) {
|
||||
@ -1503,13 +1579,18 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
|
||||
0,
|
||||
font->fd_dict[0],
|
||||
font->private_dict);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_cff_font_write_local_sub (font,
|
||||
0,
|
||||
font->private_dict,
|
||||
&font->local_sub_index);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef cairo_status_t
|
||||
@ -1521,8 +1602,8 @@ static const font_write_t font_write_funcs[] = {
|
||||
cairo_cff_font_write_top_dict,
|
||||
cairo_cff_font_write_strings,
|
||||
cairo_cff_font_write_global_subrs,
|
||||
cairo_cff_font_write_fdselect,
|
||||
cairo_cff_font_write_charset,
|
||||
cairo_cff_font_write_fdselect,
|
||||
cairo_cff_font_write_charstrings,
|
||||
cairo_cff_font_write_cid_fontdict,
|
||||
cairo_cff_font_write_cid_private_dict_and_local_sub,
|
||||
@ -1669,7 +1750,8 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
name = malloc (size);
|
||||
if (name == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0,
|
||||
(unsigned char *) name, &size);
|
||||
@ -1678,7 +1760,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font = malloc (sizeof (cairo_cff_font_t));
|
||||
if (font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
@ -1692,8 +1774,8 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font->subset_font_name = strdup (subset_name);
|
||||
if (font->subset_font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail3;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
font->x_min = (int16_t) be16_to_cpu (head.x_min);
|
||||
font->y_min = (int16_t) be16_to_cpu (head.y_min);
|
||||
@ -1728,8 +1810,8 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
if (font->font_name == NULL) {
|
||||
font->font_name = malloc (30);
|
||||
if (font->font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail4;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
snprintf(font->font_name, 30, "CairoFont-%u-%u",
|
||||
scaled_font_subset->font_id,
|
||||
@ -1745,26 +1827,36 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
|
||||
if (font->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail5;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail4;
|
||||
}
|
||||
cairo_cff_font_create_set_widths (font);
|
||||
|
||||
status = cairo_cff_font_create_set_widths (font);
|
||||
if (status)
|
||||
goto fail5;
|
||||
|
||||
font->data_length = data_length;
|
||||
font->data = malloc (data_length);
|
||||
if (font->data == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail6;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail5;
|
||||
}
|
||||
status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_CFF, 0, font->data,
|
||||
&font->data_length);
|
||||
if (status)
|
||||
goto fail7;
|
||||
goto fail6;
|
||||
|
||||
font->data_end = font->data + font->data_length;
|
||||
|
||||
cff_dict_init (&font->top_dict);
|
||||
cff_dict_init (&font->private_dict);
|
||||
status = cff_dict_init (&font->top_dict);
|
||||
if (status)
|
||||
goto fail6;
|
||||
|
||||
status = cff_dict_init (&font->private_dict);
|
||||
if (status)
|
||||
goto fail7;
|
||||
|
||||
cff_index_init (&font->strings_index);
|
||||
cff_index_init (&font->charstrings_index);
|
||||
cff_index_init (&font->global_sub_index);
|
||||
@ -1785,20 +1877,21 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail7:
|
||||
free (font->data);
|
||||
_cairo_hash_table_destroy (font->top_dict);
|
||||
fail6:
|
||||
free (font->widths);
|
||||
free (font->data);
|
||||
fail5:
|
||||
free (font->font_name);
|
||||
free (font->widths);
|
||||
fail4:
|
||||
free (font->subset_font_name);
|
||||
free (font->font_name);
|
||||
fail3:
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font->subset_font_name);
|
||||
fail2:
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font);
|
||||
fail1:
|
||||
free (name);
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1878,12 +1971,16 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
||||
goto fail1;
|
||||
|
||||
cff_subset->base_font = strdup (font->font_name);
|
||||
if (cff_subset->base_font == NULL)
|
||||
if (cff_subset->base_font == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (cff_subset->widths == NULL)
|
||||
if (cff_subset->widths == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
cff_subset->widths[i] = font->widths[i];
|
||||
|
||||
@ -1895,8 +1992,10 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
||||
cff_subset->descent = font->descent;
|
||||
|
||||
cff_subset->data = malloc (length);
|
||||
if (cff_subset->data == NULL)
|
||||
if (cff_subset->data == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
memcpy (cff_subset->data, data, length);
|
||||
cff_subset->data_length = length;
|
||||
@ -1912,7 +2011,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
||||
fail1:
|
||||
cairo_cff_font_destroy (font);
|
||||
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1933,7 +2032,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
|
||||
|
||||
font = malloc (sizeof (cairo_cff_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->backend = NULL;
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
@ -1945,14 +2044,14 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
|
||||
|
||||
font->subset_font_name = strdup (subset_name);
|
||||
if (font->subset_font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail2;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
font->font_name = strdup (subset_name);
|
||||
if (font->subset_font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail3;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
font->x_min = 0;
|
||||
@ -1964,16 +2063,22 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
|
||||
|
||||
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
|
||||
if (font->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail4;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
font->data_length = 0;
|
||||
font->data = NULL;
|
||||
font->data_end = 0;
|
||||
font->data_end = NULL;
|
||||
|
||||
status = cff_dict_init (&font->top_dict);
|
||||
if (status)
|
||||
goto fail4;
|
||||
|
||||
status = cff_dict_init (&font->private_dict);
|
||||
if (status)
|
||||
goto fail5;
|
||||
|
||||
cff_dict_init (&font->top_dict);
|
||||
cff_dict_init (&font->private_dict);
|
||||
cff_index_init (&font->strings_index);
|
||||
cff_index_init (&font->charstrings_index);
|
||||
cff_index_init (&font->global_sub_index);
|
||||
@ -1992,15 +2097,18 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail5:
|
||||
_cairo_hash_table_destroy (font->top_dict);
|
||||
fail4:
|
||||
free (font->font_name);
|
||||
free (font->widths);
|
||||
fail3:
|
||||
free (font->subset_font_name);
|
||||
free (font->font_name);
|
||||
fail2:
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font->subset_font_name);
|
||||
fail1:
|
||||
_cairo_array_fini (&font->output);
|
||||
free (font);
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -2029,16 +2137,40 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
|
||||
end_buf = encode_integer (end_buf, type2_subset->y_min);
|
||||
end_buf = encode_integer (end_buf, type2_subset->x_max);
|
||||
end_buf = encode_integer (end_buf, type2_subset->y_max);
|
||||
cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf);
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
FONTBBOX_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
end_buf = encode_integer_max (buf, 0);
|
||||
cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
|
||||
cairo_cff_font_set_ros_strings (font);
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
CHARSTRINGS_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
FDSELECT_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
FDARRAY_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cff_dict_set_operands (font->top_dict,
|
||||
CHARSET_OP, buf, end_buf - buf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_cff_font_set_ros_strings (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Create CID FD dictionary */
|
||||
cairo_cff_font_create_cid_fontdict (font);
|
||||
status = cairo_cff_font_create_cid_fontdict (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Create charstrings */
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
@ -2084,15 +2216,19 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
|
||||
|
||||
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
|
||||
if (status)
|
||||
goto fail1;
|
||||
goto fail2;
|
||||
|
||||
cff_subset->base_font = strdup (font->font_name);
|
||||
if (cff_subset->base_font == NULL)
|
||||
goto fail1;
|
||||
if (cff_subset->base_font == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (cff_subset->widths == NULL)
|
||||
goto fail2;
|
||||
if (cff_subset->widths == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
cff_subset->widths[i] = type2_subset.widths[i];
|
||||
|
||||
@ -2103,24 +2239,27 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
|
||||
cff_subset->ascent = type2_subset.y_max;
|
||||
cff_subset->descent = type2_subset.y_min;
|
||||
|
||||
_cairo_type2_charstrings_fini (&type2_subset);
|
||||
|
||||
cff_subset->data = malloc (length);
|
||||
if (cff_subset->data == NULL)
|
||||
goto fail3;
|
||||
if (cff_subset->data == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
memcpy (cff_subset->data, data, length);
|
||||
cff_subset->data_length = length;
|
||||
cff_subset->data_length = length;
|
||||
|
||||
_cairo_type2_charstrings_fini (&type2_subset);
|
||||
cairo_cff_font_destroy (font);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail3:
|
||||
fail4:
|
||||
free (cff_subset->widths);
|
||||
fail2:
|
||||
fail3:
|
||||
free (cff_subset->base_font);
|
||||
fail2:
|
||||
_cairo_type2_charstrings_fini (&type2_subset);
|
||||
fail1:
|
||||
cairo_cff_font_destroy (font);
|
||||
|
||||
|
||||
@ -36,22 +36,25 @@
|
||||
#ifndef CAIRO_CLIP_PRIVATE_H
|
||||
#define CAIRO_CLIP_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
|
||||
|
||||
struct _cairo_clip_path {
|
||||
unsigned int ref_count;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
cairo_clip_path_t *prev;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_fill_rule_t fill_rule;
|
||||
double tolerance;
|
||||
cairo_antialias_t antialias;
|
||||
cairo_clip_path_t *prev;
|
||||
};
|
||||
|
||||
struct _cairo_clip {
|
||||
cairo_clip_mode_t mode;
|
||||
|
||||
cairo_bool_t all_clipped;
|
||||
|
||||
/*
|
||||
* Mask-based clipping for cases where the backend
|
||||
* clipping isn't sufficiently able.
|
||||
|
||||
@ -54,6 +54,8 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
else
|
||||
clip->mode = CAIRO_CLIP_MODE_MASK;
|
||||
|
||||
clip->all_clipped = FALSE;
|
||||
|
||||
clip->surface = NULL;
|
||||
clip->surface_rect.x = 0;
|
||||
clip->surface_rect.y = 0;
|
||||
@ -73,6 +75,8 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
{
|
||||
clip->mode = other->mode;
|
||||
|
||||
clip->all_clipped = other->all_clipped;
|
||||
|
||||
clip->surface = cairo_surface_reference (other->surface);
|
||||
clip->surface_rect = other->surface_rect;
|
||||
|
||||
@ -81,12 +85,12 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
if (other->has_region) {
|
||||
if (_cairo_region_copy (&clip->region, &other->region) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_status_t status;
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
if (status) {
|
||||
_cairo_region_fini (&clip->region);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return status;
|
||||
}
|
||||
clip->has_region = TRUE;
|
||||
} else {
|
||||
@ -101,6 +105,8 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
void
|
||||
_cairo_clip_reset (cairo_clip_t *clip)
|
||||
{
|
||||
clip->all_clipped = FALSE;
|
||||
|
||||
/* destroy any existing clip-region artifacts */
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = NULL;
|
||||
@ -121,9 +127,19 @@ _cairo_clip_reset (cairo_clip_t *clip)
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_clip_set_all_clipped (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
{
|
||||
_cairo_clip_reset (clip);
|
||||
|
||||
clip->all_clipped = TRUE;
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
while (clip_path) {
|
||||
cairo_status_t status;
|
||||
@ -161,6 +177,11 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->all_clipped) {
|
||||
*rectangle = clip->surface_rect;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (clip->path) {
|
||||
cairo_status_t status;
|
||||
|
||||
@ -203,6 +224,18 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->all_clipped) {
|
||||
cairo_region_t clip_rect;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect clip path into region. */
|
||||
}
|
||||
@ -244,6 +277,9 @@ _cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
|
||||
|
||||
status = _cairo_surface_composite (op,
|
||||
@ -277,7 +313,7 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
|
||||
|
||||
clip_path = malloc (sizeof (cairo_clip_path_t));
|
||||
if (clip_path == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
|
||||
if (status) {
|
||||
@ -285,7 +321,7 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
|
||||
return status;
|
||||
}
|
||||
|
||||
clip_path->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
|
||||
clip_path->fill_rule = fill_rule;
|
||||
clip_path->tolerance = tolerance;
|
||||
clip_path->antialias = antialias;
|
||||
@ -301,7 +337,9 @@ _cairo_clip_path_reference (cairo_clip_path_t *clip_path)
|
||||
if (clip_path == NULL)
|
||||
return NULL;
|
||||
|
||||
clip_path->ref_count++;
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&clip_path->ref_count);
|
||||
|
||||
return clip_path;
|
||||
}
|
||||
@ -312,8 +350,9 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
|
||||
if (clip_path == NULL)
|
||||
return;
|
||||
|
||||
clip_path->ref_count--;
|
||||
if (clip_path->ref_count)
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_path_fixed_fini (&clip_path->path);
|
||||
@ -321,6 +360,7 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
|
||||
free (clip_path);
|
||||
}
|
||||
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_clip_intersect_region (cairo_clip_t *clip,
|
||||
cairo_traps_t *traps,
|
||||
@ -329,6 +369,9 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
|
||||
cairo_region_t region;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->mode != CAIRO_CLIP_MODE_REGION)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
@ -360,6 +403,9 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
_cairo_region_fini (®ion);
|
||||
|
||||
if (! _cairo_region_not_empty (&clip->region))
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -375,6 +421,9 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* Represent the clip as a mask surface. We create a new surface
|
||||
* the size of the intersection of the old mask surface and the
|
||||
* extents of the new clip path. */
|
||||
@ -392,20 +441,30 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
|
||||
if (!status)
|
||||
_cairo_rectangle_intersect (&surface_rect, &target_rect);
|
||||
|
||||
if (surface_rect.width == 0 || surface_rect.height == 0) {
|
||||
surface = NULL;
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
if (clip->surface != NULL)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
surface = _cairo_surface_create_similar_solid (target,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
surface_rect.width,
|
||||
surface_rect.height,
|
||||
CAIRO_COLOR_WHITE,
|
||||
NULL);
|
||||
if (surface->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
&pattern.base);
|
||||
if (surface->status) {
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
return surface->status;
|
||||
}
|
||||
|
||||
/* Render the new clipping path into the new mask surface. */
|
||||
|
||||
_cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
|
||||
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
|
||||
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
@ -453,10 +512,14 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
|
||||
cairo_surface_destroy (clip->surface);
|
||||
}
|
||||
|
||||
DONE:
|
||||
clip->surface = surface;
|
||||
clip->surface_rect = surface_rect;
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
|
||||
if (surface_rect.width == 0 || surface_rect.height == 0)
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -471,6 +534,15 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* catch the empty clip path */
|
||||
if (! path->has_current_point) {
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = _cairo_clip_intersect_path (clip,
|
||||
path, fill_rule, tolerance,
|
||||
antialias);
|
||||
@ -505,6 +577,9 @@ _cairo_clip_translate (cairo_clip_t *clip,
|
||||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty)
|
||||
{
|
||||
if (clip->all_clipped)
|
||||
return;
|
||||
|
||||
if (clip->has_region) {
|
||||
_cairo_region_translate (&clip->region,
|
||||
_cairo_fixed_integer_part (tx),
|
||||
@ -531,18 +606,23 @@ _cairo_clip_translate (cairo_clip_t *clip,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_reapply_clip_path (cairo_clip_t *clip,
|
||||
cairo_clip_path_t *clip_path)
|
||||
{
|
||||
if (clip_path->prev)
|
||||
_cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_clip_intersect_path (clip,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias);
|
||||
if (clip_path->prev) {
|
||||
status = _cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
|
||||
return _cairo_clip_intersect_path (clip,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -550,6 +630,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
||||
cairo_clip_t *other,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_clip_init (clip, target);
|
||||
|
||||
if (other->mode != clip->mode) {
|
||||
@ -557,26 +639,30 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
||||
* whatever the right handling is happen */
|
||||
} else {
|
||||
if (other->has_region) {
|
||||
if (_cairo_region_copy (&clip->region, &other->region) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
clip->has_region = TRUE;
|
||||
}
|
||||
|
||||
if (other->surface) {
|
||||
if (_cairo_surface_clone_similar (target, other->surface,
|
||||
other->surface_rect.x,
|
||||
other->surface_rect.y,
|
||||
other->surface_rect.width,
|
||||
other->surface_rect.height,
|
||||
&clip->surface) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_surface_clone_similar (target, other->surface,
|
||||
other->surface_rect.x,
|
||||
other->surface_rect.y,
|
||||
other->surface_rect.width,
|
||||
other->surface_rect.height,
|
||||
&clip->surface);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
clip->surface_rect = other->surface_rect;
|
||||
}
|
||||
|
||||
if (other->path) {
|
||||
_cairo_clip_path_reapply_clip_path (clip, other->path);
|
||||
status = _cairo_clip_path_reapply_clip_path (clip, other->path);
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,7 +674,7 @@ BAIL:
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return status;
|
||||
}
|
||||
|
||||
const cairo_rectangle_list_t _cairo_rectangles_nil =
|
||||
@ -623,7 +709,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
int n_boxes;
|
||||
int n_boxes = 0;
|
||||
|
||||
if (clip->all_clipped)
|
||||
goto DONE;
|
||||
|
||||
if (clip->path || clip->surface)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
@ -635,23 +724,26 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
|
||||
boxes[i].p2.x - boxes[i].p1.x,
|
||||
boxes[i].p2.y - boxes[i].p1.y };
|
||||
|
||||
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
|
||||
if (n_boxes) {
|
||||
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
|
||||
boxes[i].p2.x - boxes[i].p1.x,
|
||||
boxes[i].p2.y - boxes[i].p1.y };
|
||||
|
||||
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
} else {
|
||||
@ -660,8 +752,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
n_boxes = 1;
|
||||
|
||||
rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL)
|
||||
if (rectangles == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
|
||||
!_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
|
||||
@ -671,9 +765,11 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
if (list == NULL) {
|
||||
free (rectangles);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
|
||||
115
mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h
Normal file
115
mozilla/gfx/cairo/cairo/src/cairo-compiler-private.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_COMPILER_PRIVATE_H
|
||||
#define CAIRO_COMPILER_PRIVATE_H
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
|
||||
# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_int_name(name) INT_##name
|
||||
# define slim_hidden_proto1(name, internal) \
|
||||
extern __typeof (name) name \
|
||||
__asm__ (slim_hidden_asmname (internal))
|
||||
# define slim_hidden_def1(name, internal) \
|
||||
extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \
|
||||
__attribute__((__alias__(slim_hidden_asmname(internal))))
|
||||
# define slim_hidden_ulp slim_hidden_ulp1(__USER_LABEL_PREFIX__)
|
||||
# define slim_hidden_ulp1(x) slim_hidden_ulp2(x)
|
||||
# define slim_hidden_ulp2(x) #x
|
||||
# define slim_hidden_asmname(name) slim_hidden_asmname1(name)
|
||||
# define slim_hidden_asmname1(name) slim_hidden_ulp #name
|
||||
#else
|
||||
# define slim_hidden_proto(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_def(name) int _cairo_dummy_prototype(void)
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
|
||||
__attribute__((__format__(__printf__, fmt_index, va_index)))
|
||||
#else
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
|
||||
#endif
|
||||
|
||||
/* slim_internal.h */
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
|
||||
#define cairo_private_no_warn __attribute__((__visibility__("hidden")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
#define cairo_private_no_warn __hidden
|
||||
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
|
||||
#define cairo_private_no_warn
|
||||
#endif
|
||||
|
||||
#ifndef WARN_UNUSED_RESULT
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
/* Add attribute(warn_unused_result) if supported */
|
||||
#define cairo_warn WARN_UNUSED_RESULT
|
||||
#define cairo_private cairo_private_no_warn cairo_warn
|
||||
|
||||
/* This macro allow us to deprecate a function by providing an alias
|
||||
for the old function name to the new function name. With this
|
||||
macro, binary compatibility is preserved. The macro only works on
|
||||
some platforms --- tough.
|
||||
|
||||
Meanwhile, new definitions in the public header file break the
|
||||
source code so that it will no longer link against the old
|
||||
symbols. Instead it will give a descriptive error message
|
||||
indicating that the old function has been deprecated by the new
|
||||
function.
|
||||
*/
|
||||
#if __GNUC__ >= 2 && defined(__ELF__)
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new) \
|
||||
extern __typeof (new) old \
|
||||
__asm__ ("" #old) \
|
||||
__attribute__((__alias__("" #new)))
|
||||
#else
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new)
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
@ -59,6 +59,8 @@
|
||||
void
|
||||
cairo_debug_reset_static_data (void)
|
||||
{
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
_cairo_font_reset_static_data ();
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
@ -66,4 +68,6 @@ cairo_debug_reset_static_data (void)
|
||||
#endif
|
||||
|
||||
_cairo_pattern_reset_static_data ();
|
||||
|
||||
CAIRO_MUTEX_FINALIZE ();
|
||||
}
|
||||
|
||||
@ -117,9 +117,17 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_deflate_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_deflate_stream_t));
|
||||
if (stream == NULL)
|
||||
if (output->status) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
|
||||
stream = malloc (sizeof (cairo_deflate_stream_t));
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base,
|
||||
_cairo_deflate_stream_write,
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
#define DFB_SHOW_GLYPHS 1
|
||||
|
||||
|
||||
D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend");
|
||||
D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend")
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -390,7 +390,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||
if( buffer != surface->dfbsurface)
|
||||
buffer->Release(buffer);
|
||||
}
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
@ -414,8 +414,10 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
||||
|
||||
format = _cairo_format_from_content (content);
|
||||
surface = calloc (1, sizeof(cairo_directfb_surface_t));
|
||||
if (!surface)
|
||||
if (!surface) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->dfbsurface = _directfb_buffer_surface_create (source->dfb,
|
||||
cairo_to_directfb_format (format),
|
||||
@ -528,12 +530,12 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf
|
||||
buffer->Unlock (buffer);
|
||||
|
||||
if (surface->dfbsurface != buffer) {
|
||||
DFBRegion region = { x1:interest_rect->x, y1:interest_rect->y,
|
||||
x2:interest_rect->x+interest_rect->width-1,
|
||||
y2:interest_rect->y+interest_rect->height-1 };
|
||||
DFBRegion region = { .x1 = interest_rect->x, .y1 = interest_rect->y,
|
||||
.x2 = interest_rect->x+interest_rect->width-1,
|
||||
.y2 = interest_rect->y+interest_rect->height-1 };
|
||||
surface->dfbsurface->SetClip (surface->dfbsurface, ®ion);
|
||||
//surface->dfbsurface->SetBlittingFlags (surface->dfbsurface,
|
||||
// DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE);
|
||||
/* surface->dfbsurface->SetBlittingFlags (surface->dfbsurface,
|
||||
DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE); */
|
||||
surface->dfbsurface->Blit (surface->dfbsurface,buffer,NULL,
|
||||
image_rect->x,image_rect->y);
|
||||
buffer->Release (buffer);
|
||||
@ -574,14 +576,14 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
||||
_cairo_content_from_format (image_src->format),
|
||||
image_src->width, image_src->height);
|
||||
if (!clone)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
ret = clone->dfbsurface->Lock (clone->dfbsurface,
|
||||
DSLF_WRITE, (void *)&dst, &pitch);
|
||||
if (ret) {
|
||||
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
||||
cairo_surface_destroy ((cairo_surface_t *)clone);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
dst += pitch * src_y;
|
||||
@ -664,7 +666,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||
if (sblend == DSBF_ONE) {
|
||||
flags |= DSBLIT_BLEND_ALPHACHANNEL;
|
||||
sblend = DSBF_SRCALPHA;
|
||||
//dblend = DSBF_INVSRCALPHA;
|
||||
/* dblend = DSBF_INVSRCALPHA; */
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +687,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||
dst->color = _cairo_directfb_surface_create_similar (dst,
|
||||
CAIRO_CONTENT_COLOR_ALPHA, 1, 1);
|
||||
if (!dst->color)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
src = (cairo_directfb_surface_t *)dst->color;
|
||||
@ -756,7 +758,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_directfb_surface_t *dst = abstract_dst;
|
||||
cairo_directfb_surface_t *src;
|
||||
cairo_directfb_surface_t *src = NULL; /* hide compiler warning */
|
||||
cairo_surface_attributes_t src_attr;
|
||||
cairo_matrix_t *m;
|
||||
cairo_status_t ret;
|
||||
@ -1107,9 +1109,11 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
if (region) {
|
||||
cairo_box_int_t *boxes;
|
||||
int n_boxes, i;
|
||||
cairo_status_t status;
|
||||
|
||||
if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (surface->n_clips != n_boxes) {
|
||||
if( surface->clips )
|
||||
@ -1119,7 +1123,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
if (!surface->clips) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
surface->n_clips = 0;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
surface->n_clips = n_boxes;
|
||||
@ -1181,7 +1185,7 @@ _cairo_directfb_surface_mark_dirty_rectangle (void *abstract_surface,
|
||||
if( !surface->dirty_region )
|
||||
surface->dirty_region = malloc(sizeof(DFBRegion));
|
||||
if (!dirty_region)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
#endif
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1211,16 +1215,19 @@ _directfb_allocate_font_cache (IDirectFB *dfb, int width, int height)
|
||||
cairo_directfb_font_cache_t *cache;
|
||||
|
||||
cache = calloc (1, sizeof(cairo_directfb_font_cache_t));
|
||||
if (!cache)
|
||||
return NULL;
|
||||
if (!cache) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cache->dfbsurface = _directfb_buffer_surface_create( dfb, DSPF_A8, width, height);
|
||||
if (!cache->dfbsurface) {
|
||||
free (cache);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//dfb->AddRef (dfb);
|
||||
/* dfb->AddRef (dfb); */
|
||||
cache->dfb = dfb;
|
||||
|
||||
cache->width = width;
|
||||
@ -1314,7 +1321,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||
/* Remember glyph location */
|
||||
rect = malloc (sizeof(DFBRectangle));
|
||||
if (!rect)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
*rect = rects[n];
|
||||
|
||||
scaled_glyph->surface_private = rect;
|
||||
@ -1352,7 +1359,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||
|
||||
new_cache = _directfb_allocate_font_cache (surface->dfb, w, h);
|
||||
if (!new_cache)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
new_cache->dfbsurface->Blit (new_cache->dfbsurface,
|
||||
cache->dfbsurface, NULL, 0, 0);
|
||||
@ -1366,8 +1373,8 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||
"Allocating font cache (%dx%d).\n", w, h);
|
||||
|
||||
cache = _directfb_allocate_font_cache (surface->dfb, w, h);
|
||||
if (!cache)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (!cache)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
scaled_font->surface_backend = &cairo_directfb_surface_backend;
|
||||
scaled_font->surface_private = cache;
|
||||
@ -1379,7 +1386,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||
|
||||
if (cache->dfbsurface->Lock (cache->dfbsurface,
|
||||
DSLF_WRITE, (void *)&data, &pitch))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
for (i = 0; i < num_chars; i++) {
|
||||
cairo_image_surface_t *img = chars[i]->surface;
|
||||
@ -1629,8 +1636,10 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
|
||||
cairo_directfb_surface_backend_init (dfb);
|
||||
|
||||
surface = calloc (1, sizeof(cairo_directfb_surface_t));
|
||||
if (!surface)
|
||||
return NULL;
|
||||
if (!surface) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dfbsurface->GetPixelFormat (dfbsurface, &format);
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend,
|
||||
|
||||
@ -53,9 +53,9 @@
|
||||
|
||||
#define CAIRO_VERSION_MAJOR 1
|
||||
#define CAIRO_VERSION_MINOR 5
|
||||
#define CAIRO_VERSION_MICRO 1
|
||||
#define CAIRO_VERSION_MICRO 3
|
||||
|
||||
#define CAIRO_VERSION_STRING "1.5.1"
|
||||
#define CAIRO_VERSION_STRING "1.5.3"
|
||||
|
||||
@PS_SURFACE_FEATURE@
|
||||
|
||||
|
||||
@ -55,7 +55,10 @@ typedef cairo_int128_t cairo_fixed_96_32_t;
|
||||
*/
|
||||
#define CAIRO_FIXED_BITS 32
|
||||
|
||||
/* The number of fractional bits. */
|
||||
/* The number of fractional bits. Changing this involves
|
||||
* making sure that you compute a double-to-fixed magic number.
|
||||
* (see below).
|
||||
*/
|
||||
#define CAIRO_FIXED_FRAC_BITS 8
|
||||
|
||||
/* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */
|
||||
@ -206,12 +209,13 @@ _cairo_fixed_to_16_16 (cairo_fixed_t f)
|
||||
#if (CAIRO_FIXED_FRAC_BITS == 16) && (CAIRO_FIXED_BITS == 32)
|
||||
return f;
|
||||
#elif CAIRO_FIXED_FRAC_BITS > 16
|
||||
/* We're just dropping the low bits, so we won't ever got over/underflow here */
|
||||
return f >> (CAIRO_FIXED_FRAC_BITS - 16);
|
||||
#else
|
||||
cairo_fixed_16_16_t x;
|
||||
|
||||
/* Clamp to INT16 so that we don't get odd overflow or underflow by
|
||||
* just shifting.
|
||||
/* Handle overflow/underflow by claping to the lowest/highest
|
||||
* value representable as 16.16
|
||||
*/
|
||||
if ((f >> CAIRO_FIXED_FRAC_BITS) < INT16_MIN) {
|
||||
x = INT32_MIN;
|
||||
|
||||
@ -50,11 +50,23 @@ static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
||||
const cairo_font_face_t _cairo_font_face_nil = {
|
||||
{ 0 }, /* hash_entry */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
&_cairo_toy_font_face_backend
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
_cairo_font_face_set_error (cairo_font_face_t *font_face,
|
||||
cairo_status_t status)
|
||||
{
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
_cairo_status_set_error (&font_face->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_font_face_init (cairo_font_face_t *font_face,
|
||||
const cairo_font_face_backend_t *backend)
|
||||
@ -62,7 +74,7 @@ _cairo_font_face_init (cairo_font_face_t *font_face,
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
font_face->status = CAIRO_STATUS_SUCCESS;
|
||||
font_face->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
|
||||
font_face->backend = backend;
|
||||
|
||||
_cairo_user_data_array_init (&font_face->user_data);
|
||||
@ -85,18 +97,15 @@ _cairo_font_face_init (cairo_font_face_t *font_face,
|
||||
cairo_font_face_t *
|
||||
cairo_font_face_reference (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return font_face;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
|
||||
|
||||
/* We would normally assert (font_face->ref_count >0) here but we
|
||||
/* We would normally assert that we have a reference here but we
|
||||
* can't get away with that due to the zombie case as documented
|
||||
* in _cairo_ft_font_face_destroy. */
|
||||
|
||||
font_face->ref_count++;
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
_cairo_reference_count_inc (&font_face->ref_count);
|
||||
|
||||
return font_face;
|
||||
}
|
||||
@ -113,19 +122,14 @@ slim_hidden_def (cairo_font_face_reference);
|
||||
void
|
||||
cairo_font_face_destroy (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
|
||||
|
||||
assert (font_face->ref_count > 0);
|
||||
|
||||
if (--(font_face->ref_count) > 0) {
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
|
||||
return;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
|
||||
|
||||
font_face->backend->destroy (font_face);
|
||||
|
||||
@ -133,7 +137,7 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
|
||||
* FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
|
||||
* need to effectively mutually reference each other
|
||||
*/
|
||||
if (font_face->ref_count > 0)
|
||||
if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_user_data_array_fini (&font_face->user_data);
|
||||
@ -173,10 +177,11 @@ cairo_font_face_get_type (cairo_font_face_t *font_face)
|
||||
unsigned int
|
||||
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
|
||||
{
|
||||
if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return 0;
|
||||
|
||||
return font_face->ref_count;
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,8 +242,8 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return _cairo_user_data_array_set_data (&font_face->user_data,
|
||||
key, user_data, destroy);
|
||||
@ -315,6 +320,7 @@ _cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
|
||||
hash += ((unsigned long) slant) * 1607;
|
||||
hash += ((unsigned long) weight) * 1451;
|
||||
|
||||
assert (hash != 0);
|
||||
key->base.hash_entry.hash = hash;
|
||||
}
|
||||
|
||||
@ -328,7 +334,7 @@ _cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
|
||||
|
||||
family_copy = strdup (family);
|
||||
if (family_copy == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_toy_font_face_init_key (font_face, family_copy,
|
||||
slant, weight);
|
||||
@ -393,17 +399,25 @@ _cairo_toy_font_face_create (const char *family,
|
||||
&key.base.hash_entry,
|
||||
(cairo_hash_entry_t **) &font_face))
|
||||
{
|
||||
/* We increment the reference count here manually to avoid
|
||||
double-locking. */
|
||||
font_face->base.ref_count++;
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
return &font_face->base;
|
||||
if (! font_face->base.status) {
|
||||
/* We increment the reference count here manually to avoid
|
||||
double-locking. */
|
||||
_cairo_reference_count_inc (&font_face->base.ref_count);
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
return &font_face->base;
|
||||
}
|
||||
|
||||
/* remove the bad font from the hash table */
|
||||
_cairo_hash_table_remove (hash_table, &key.base.hash_entry);
|
||||
font_face->base.hash_entry.hash = 0;
|
||||
}
|
||||
|
||||
/* Otherwise create it and insert into hash table. */
|
||||
font_face = malloc (sizeof (cairo_toy_font_face_t));
|
||||
if (font_face == NULL)
|
||||
if (font_face == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto UNWIND_HASH_TABLE_LOCK;
|
||||
}
|
||||
|
||||
status = _cairo_toy_font_face_init (font_face, family, slant, weight);
|
||||
if (status)
|
||||
@ -432,14 +446,16 @@ _cairo_toy_font_face_destroy (void *abstract_face)
|
||||
cairo_toy_font_face_t *font_face = abstract_face;
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
if (font_face == NULL)
|
||||
if (font_face == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->base.ref_count))
|
||||
return;
|
||||
|
||||
hash_table = _cairo_toy_font_face_hash_table_lock ();
|
||||
/* All created objects must have been mapped in the hash table. */
|
||||
assert (hash_table != NULL);
|
||||
|
||||
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
|
||||
if (font_face->base.hash_entry.hash != 0)
|
||||
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
|
||||
|
||||
_cairo_toy_font_face_hash_table_unlock ();
|
||||
|
||||
@ -457,12 +473,19 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
|
||||
const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font_face->base.status)
|
||||
return font_face->base.status;
|
||||
|
||||
status = cairo_font_options_status ((cairo_font_options_t *) options);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return backend->create_toy (font_face,
|
||||
font_matrix, ctm, options, scaled_font);
|
||||
return _cairo_font_face_set_error (&font_face->base,
|
||||
backend->create_toy (font_face,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options,
|
||||
scaled_font));
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
|
||||
@ -475,7 +498,7 @@ void
|
||||
_cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font,
|
||||
const cairo_unscaled_font_backend_t *backend)
|
||||
{
|
||||
unscaled_font->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
|
||||
unscaled_font->backend = backend;
|
||||
}
|
||||
|
||||
@ -485,7 +508,9 @@ _cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
|
||||
if (unscaled_font == NULL)
|
||||
return NULL;
|
||||
|
||||
unscaled_font->ref_count++;
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&unscaled_font->ref_count);
|
||||
|
||||
return unscaled_font;
|
||||
}
|
||||
@ -496,7 +521,9 @@ _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
|
||||
if (unscaled_font == NULL)
|
||||
return;
|
||||
|
||||
if (--(unscaled_font->ref_count) > 0)
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
|
||||
return;
|
||||
|
||||
unscaled_font->backend->destroy (unscaled_font);
|
||||
|
||||
@ -86,10 +86,13 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_create (void)
|
||||
{
|
||||
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
|
||||
cairo_font_options_t *options;
|
||||
|
||||
if (!options)
|
||||
options = malloc (sizeof (cairo_font_options_t));
|
||||
if (!options) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_options_t *)&_cairo_font_options_nil;
|
||||
}
|
||||
|
||||
_cairo_font_options_init_default (options);
|
||||
|
||||
@ -119,8 +122,10 @@ cairo_font_options_copy (const cairo_font_options_t *original)
|
||||
return (cairo_font_options_t *)&_cairo_font_options_nil;
|
||||
|
||||
options = malloc (sizeof (cairo_font_options_t));
|
||||
if (!options)
|
||||
if (!options) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_options_t *)&_cairo_font_options_nil;
|
||||
}
|
||||
|
||||
_cairo_font_options_init_copy (options, original);
|
||||
|
||||
|
||||
@ -119,6 +119,10 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
||||
static void
|
||||
_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern);
|
||||
|
||||
typedef enum _cairo_ft_extra_flags {
|
||||
CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
|
||||
CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
|
||||
@ -180,8 +184,10 @@ _cairo_ft_unscaled_font_map_create (void)
|
||||
assert (cairo_ft_unscaled_font_map == NULL);
|
||||
|
||||
font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
|
||||
if (font_map == NULL)
|
||||
if (font_map == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
font_map->hash_table =
|
||||
_cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
|
||||
@ -259,7 +265,7 @@ _cairo_ft_unscaled_font_map_lock (void)
|
||||
|
||||
if (cairo_ft_unscaled_font_map == NULL) {
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -332,10 +338,8 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
|
||||
unscaled->face = NULL;
|
||||
|
||||
filename_copy = strdup (filename);
|
||||
if (filename_copy == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (filename_copy == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
|
||||
}
|
||||
@ -427,8 +431,10 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
|
||||
|
||||
/* Otherwise create it and insert into hash table. */
|
||||
unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
|
||||
if (unscaled == NULL)
|
||||
if (unscaled == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto UNWIND_FONT_MAP_LOCK;
|
||||
}
|
||||
|
||||
status = _cairo_ft_unscaled_font_init (unscaled, filename, id, NULL);
|
||||
if (status)
|
||||
@ -460,8 +466,10 @@ _cairo_ft_unscaled_font_create_from_face (FT_Face face)
|
||||
cairo_ft_unscaled_font_t *unscaled;
|
||||
|
||||
unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
|
||||
if (unscaled == NULL)
|
||||
if (unscaled == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = _cairo_ft_unscaled_font_init (unscaled, NULL, 0, face);
|
||||
if (status) {
|
||||
@ -486,6 +494,8 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
|
||||
*/
|
||||
if (unscaled->faces && !unscaled->faces->unscaled)
|
||||
cairo_font_face_destroy (&unscaled->faces->base);
|
||||
|
||||
unscaled->face = NULL;
|
||||
} else {
|
||||
cairo_ft_unscaled_font_map_t *font_map;
|
||||
|
||||
@ -497,10 +507,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
|
||||
&unscaled->base.hash_entry);
|
||||
|
||||
_font_map_release_face_lock_held (font_map, unscaled);
|
||||
_cairo_ft_unscaled_font_fini (unscaled);
|
||||
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
}
|
||||
_cairo_ft_unscaled_font_fini (unscaled);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
@ -558,7 +568,7 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
|
||||
{
|
||||
unscaled->lock_count--;
|
||||
CAIRO_MUTEX_UNLOCK (unscaled->mutex);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -673,10 +683,8 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
||||
x_scale * 64.0,
|
||||
y_scale * 64.0,
|
||||
0, 0);
|
||||
if (error) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
double min_distance = DBL_MAX;
|
||||
int i;
|
||||
@ -705,10 +713,8 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
||||
error = FT_Set_Pixel_Sizes (unscaled->face,
|
||||
unscaled->face->available_sizes[best_i].width,
|
||||
unscaled->face->available_sizes[best_i].height);
|
||||
if (error) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -762,10 +768,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
assert (stride == bitmap->pitch);
|
||||
} else {
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (!data)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (stride == bitmap->pitch) {
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
@ -812,10 +816,9 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
data = bitmap->buffer;
|
||||
} else {
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (!data)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
}
|
||||
format = CAIRO_FORMAT_A8;
|
||||
@ -853,12 +856,11 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
width_rgba = width;
|
||||
stride = bitmap->pitch;
|
||||
stride_rgba = (width_rgba * 4 + 3) & ~3;
|
||||
data_rgba = calloc (1, stride_rgba * height);
|
||||
data_rgba = calloc (stride_rgba, height);
|
||||
if (data_rgba == NULL) {
|
||||
if (own_buffer)
|
||||
free (bitmap->buffer);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
os = 1;
|
||||
@ -926,8 +928,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
default:
|
||||
if (own_buffer)
|
||||
free (bitmap->buffer);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
*surface = (cairo_image_surface_t *)
|
||||
@ -936,7 +937,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
width, height, stride);
|
||||
if ((*surface)->base.status) {
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (subpixel)
|
||||
@ -1009,7 +1010,7 @@ _render_glyph_outline (FT_Face face,
|
||||
(*surface) = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
|
||||
if ((*surface)->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return (*surface)->base.status;
|
||||
} else {
|
||||
|
||||
matrix.xx = matrix.yy = 0x10000L;
|
||||
@ -1054,19 +1055,16 @@ _render_glyph_outline (FT_Face face,
|
||||
bitmap.pitch = stride;
|
||||
bitmap.width = width * hmul;
|
||||
bitmap.rows = height * vmul;
|
||||
bitmap.buffer = calloc (1, stride * bitmap.rows);
|
||||
|
||||
bitmap.buffer = calloc (stride, bitmap.rows);
|
||||
if (bitmap.buffer == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
|
||||
|
||||
if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
|
||||
free (bitmap.buffer);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
|
||||
@ -1107,10 +1105,8 @@ _render_glyph_bitmap (FT_Face face,
|
||||
error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
|
||||
/* XXX ignoring all other errors for now. They are not fatal, typically
|
||||
* just a glyph-not-found. */
|
||||
if (error == FT_Err_Out_Of_Memory) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (error == FT_Err_Out_Of_Memory)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
|
||||
if (status)
|
||||
@ -1207,7 +1203,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
width = (width + 3) & ~3;
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
|
||||
if (image->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return image->status;
|
||||
|
||||
/* Initialize it to empty
|
||||
*/
|
||||
@ -1473,15 +1469,16 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||
options->extra_flags = other->extra_flags;
|
||||
}
|
||||
|
||||
static cairo_scaled_font_t *
|
||||
static cairo_status_t
|
||||
_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_ft_options_t ft_options)
|
||||
cairo_ft_options_t ft_options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_ft_scaled_font_t *scaled_font = NULL;
|
||||
cairo_ft_scaled_font_t *scaled_font;
|
||||
FT_Face face;
|
||||
FT_Size_Metrics *metrics;
|
||||
cairo_font_extents_t fs_metrics;
|
||||
@ -1489,13 +1486,12 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return NULL;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
|
||||
if (scaled_font == NULL) {
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
_cairo_unscaled_font_reference (&unscaled->base);
|
||||
@ -1513,20 +1509,40 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
&cairo_ft_scaled_font_backend);
|
||||
if (status) {
|
||||
free (scaled_font);
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
return NULL;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
status = _cairo_ft_unscaled_font_set_scale (unscaled,
|
||||
&scaled_font->base.scale);
|
||||
if (status) {
|
||||
free (scaled_font);
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
return NULL;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force non-AA drawing when using a bitmap strike that
|
||||
* won't be resampled due to non-scaling transform
|
||||
*/
|
||||
if (!unscaled->have_shape &&
|
||||
(scaled_font->ft_options.load_flags & FT_LOAD_NO_BITMAP) == 0 &&
|
||||
scaled_font->ft_options.base.antialias != CAIRO_ANTIALIAS_NONE &&
|
||||
(face->face_flags & FT_FACE_FLAG_FIXED_SIZES))
|
||||
{
|
||||
int i;
|
||||
FT_Size_Metrics *size_metrics = &face->size->metrics;
|
||||
|
||||
for (i = 0; i < face->num_fixed_sizes; i++)
|
||||
{
|
||||
FT_Bitmap_Size *bitmap_size = &face->available_sizes[i];
|
||||
|
||||
if (bitmap_size->x_ppem == size_metrics->x_ppem * 64 &&
|
||||
bitmap_size->y_ppem == size_metrics->y_ppem * 64)
|
||||
{
|
||||
scaled_font->ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metrics = &face->size->metrics;
|
||||
|
||||
@ -1574,9 +1590,12 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
|
||||
_cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
|
||||
|
||||
*font_out = &scaled_font->base;
|
||||
|
||||
FAIL:
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
|
||||
return &scaled_font->base;
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
@ -1594,30 +1613,23 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
{
|
||||
FcPattern *pattern, *resolved;
|
||||
cairo_ft_unscaled_font_t *unscaled;
|
||||
cairo_scaled_font_t *new_font = NULL;
|
||||
FcResult result;
|
||||
int fcslant;
|
||||
int fcweight;
|
||||
cairo_matrix_t scale;
|
||||
cairo_status_t status;
|
||||
cairo_ft_font_transform_t sf;
|
||||
cairo_ft_options_t ft_options;
|
||||
unsigned char *family = (unsigned char*) toy_face->family;
|
||||
|
||||
pattern = FcPatternCreate ();
|
||||
if (!pattern) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (!pattern)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
switch (toy_face->weight)
|
||||
if (!FcPatternAddString (pattern,
|
||||
FC_FAMILY, (unsigned char *) toy_face->family))
|
||||
{
|
||||
case CAIRO_FONT_WEIGHT_BOLD:
|
||||
fcweight = FC_WEIGHT_BOLD;
|
||||
break;
|
||||
case CAIRO_FONT_WEIGHT_NORMAL:
|
||||
default:
|
||||
fcweight = FC_WEIGHT_MEDIUM;
|
||||
break;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
switch (toy_face->slant)
|
||||
@ -1634,36 +1646,65 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!FcPatternAddString (pattern, FC_FAMILY, family))
|
||||
if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))
|
||||
goto FREE_PATTERN;
|
||||
if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight))
|
||||
}
|
||||
|
||||
switch (toy_face->weight)
|
||||
{
|
||||
case CAIRO_FONT_WEIGHT_BOLD:
|
||||
fcweight = FC_WEIGHT_BOLD;
|
||||
break;
|
||||
case CAIRO_FONT_WEIGHT_NORMAL:
|
||||
default:
|
||||
fcweight = FC_WEIGHT_MEDIUM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
cairo_matrix_multiply (&scale, font_matrix, ctm);
|
||||
_compute_transform (&sf, &scale);
|
||||
|
||||
FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
|
||||
if (! FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
status = _cairo_ft_font_options_substitute (font_options, pattern);
|
||||
if (status)
|
||||
goto FREE_PATTERN;
|
||||
|
||||
FcConfigSubstitute (NULL, pattern, FcMatchPattern);
|
||||
cairo_ft_font_options_substitute (font_options, pattern);
|
||||
FcDefaultSubstitute (pattern);
|
||||
|
||||
resolved = FcFontMatch (NULL, pattern, &result);
|
||||
if (!resolved)
|
||||
if (!resolved) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
|
||||
if (!unscaled)
|
||||
if (!unscaled) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_RESOLVED;
|
||||
}
|
||||
|
||||
_get_pattern_ft_options (resolved, &ft_options);
|
||||
|
||||
new_font = _cairo_ft_scaled_font_create (unscaled,
|
||||
&toy_face->base,
|
||||
font_matrix, ctm,
|
||||
font_options, ft_options);
|
||||
status = _cairo_ft_scaled_font_create (unscaled,
|
||||
&toy_face->base,
|
||||
font_matrix, ctm,
|
||||
font_options, ft_options,
|
||||
font);
|
||||
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
|
||||
@ -1673,13 +1714,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
FREE_PATTERN:
|
||||
FcPatternDestroy (pattern);
|
||||
|
||||
if (new_font) {
|
||||
*font = new_font;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
} else {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1736,8 +1771,7 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
|
||||
cairo_fixed_t x3, y3;
|
||||
cairo_point_t conic;
|
||||
|
||||
if (_cairo_path_fixed_get_current_point (path, &x0, &y0) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
if (! _cairo_path_fixed_get_current_point (path, &x0, &y0))
|
||||
return 1;
|
||||
|
||||
conic.x = _cairo_fixed_from_26_6 (control->x);
|
||||
@ -1812,7 +1846,7 @@ _decompose_glyph_outline (FT_Face face,
|
||||
|
||||
path = _cairo_path_fixed_create ();
|
||||
if (!path)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
glyph = face->glyph;
|
||||
|
||||
@ -1820,8 +1854,7 @@ _decompose_glyph_outline (FT_Face face,
|
||||
FT_Outline_Transform (&glyph->outline, &invert_y);
|
||||
if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
|
||||
_cairo_path_fixed_destroy (path);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_close_path (path);
|
||||
@ -1876,7 +1909,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
|
||||
&scaled_font->base.scale);
|
||||
@ -1905,7 +1938,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
/* XXX ignoring all other errors for now. They are not fatal, typically
|
||||
* just a glyph-not-found. */
|
||||
if (error == FT_Err_Out_Of_Memory) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
@ -2044,7 +2077,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
}
|
||||
|
||||
if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
|
||||
cairo_path_fixed_t *path;
|
||||
cairo_path_fixed_t *path = NULL; /* hide compiler warning */
|
||||
|
||||
/*
|
||||
* A kludge -- the above code will trash the outline,
|
||||
@ -2057,9 +2090,8 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
/* XXX ignoring all other errors for now. They are not fatal, typically
|
||||
* just a glyph-not-found. */
|
||||
if (error == FT_Err_Out_Of_Memory) {
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
|
||||
/*
|
||||
@ -2126,7 +2158,7 @@ _cairo_ft_load_truetype_table (void *abstract_font,
|
||||
#if HAVE_FT_LOAD_SFNT_TABLE
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (FT_IS_SFNT (face) &&
|
||||
FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
|
||||
@ -2211,7 +2243,7 @@ _cairo_ft_font_face_destroy (void *abstract_face)
|
||||
|
||||
if (font_face->unscaled &&
|
||||
font_face->unscaled->from_face &&
|
||||
font_face->unscaled->base.ref_count > 1)
|
||||
CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
|
||||
{
|
||||
cairo_font_face_reference (&font_face->base);
|
||||
|
||||
@ -2264,16 +2296,11 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face,
|
||||
|
||||
ft_options = font_face->ft_options;
|
||||
|
||||
*scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
|
||||
&font_face->base,
|
||||
font_matrix, ctm,
|
||||
options, ft_options);
|
||||
if (*scaled_font) {
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
} else {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
return _cairo_ft_scaled_font_create (font_face->unscaled,
|
||||
&font_face->base,
|
||||
font_matrix, ctm,
|
||||
options, ft_options,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
|
||||
@ -2309,7 +2336,7 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
/* No match found, create a new one */
|
||||
font_face = malloc (sizeof (cairo_ft_font_face_t));
|
||||
if (!font_face) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2328,20 +2355,9 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
|
||||
/* implement the platform-specific interface */
|
||||
|
||||
/**
|
||||
* cairo_ft_font_options_substitute:
|
||||
* @options: a #cairo_font_options_t object
|
||||
* @pattern: an existing #FcPattern
|
||||
*
|
||||
* Add options to a #FcPattern based on a #cairo_font_options_t font
|
||||
* options object. Options that are already in the pattern, are not overridden,
|
||||
* so you should call this function after calling FcConfigSubstitute() (the
|
||||
* user's settings should override options based on the surface type), but
|
||||
* before calling FcDefaultSubstitute().
|
||||
**/
|
||||
void
|
||||
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern)
|
||||
static cairo_status_t
|
||||
_cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern)
|
||||
{
|
||||
FcValue v;
|
||||
|
||||
@ -2349,10 +2365,15 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
|
||||
if (! FcPatternAddBool (pattern,
|
||||
FC_ANTIALIAS,
|
||||
options->antialias != CAIRO_ANTIALIAS_NONE))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
|
||||
FcPatternDel (pattern, FC_RGBA);
|
||||
FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE);
|
||||
if (! FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2384,7 +2405,8 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
rgba = FC_RGBA_NONE;
|
||||
}
|
||||
|
||||
FcPatternAddInteger (pattern, FC_RGBA, rgba);
|
||||
if (! FcPatternAddInteger (pattern, FC_RGBA, rgba))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2392,7 +2414,10 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
|
||||
if (! FcPatternAddBool (pattern,
|
||||
FC_HINTING,
|
||||
options->hint_style != CAIRO_HINT_STYLE_NONE))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
@ -2417,12 +2442,32 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
break;
|
||||
}
|
||||
|
||||
FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
|
||||
if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_ft_font_options_substitute:
|
||||
* @options: a #cairo_font_options_t object
|
||||
* @pattern: an existing #FcPattern
|
||||
*
|
||||
* Add options to a #FcPattern based on a #cairo_font_options_t font
|
||||
* options object. Options that are already in the pattern, are not overridden,
|
||||
* so you should call this function after calling FcConfigSubstitute() (the
|
||||
* user's settings should override options based on the surface type), but
|
||||
* before calling FcDefaultSubstitute().
|
||||
**/
|
||||
void
|
||||
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern)
|
||||
{
|
||||
_cairo_ft_font_options_substitute (options, pattern);
|
||||
}
|
||||
slim_hidden_def (cairo_ft_font_options_substitute);
|
||||
|
||||
/**
|
||||
* cairo_ft_font_face_create_for_pattern:
|
||||
@ -2459,7 +2504,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
|
||||
|
||||
unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
|
||||
if (unscaled == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
@ -2509,7 +2554,7 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face,
|
||||
|
||||
unscaled = _cairo_ft_unscaled_font_create_from_face (face);
|
||||
if (unscaled == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
@ -2568,7 +2613,7 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
|
||||
if (face == NULL) {
|
||||
_cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2576,7 +2621,7 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
|
||||
&scaled_font->base.scale);
|
||||
if (status) {
|
||||
_cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
|
||||
_cairo_scaled_font_set_error (&scaled_font->base, status);
|
||||
status = _cairo_scaled_font_set_error (&scaled_font->base, status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,6 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
slim_hidden_proto (cairo_ft_font_options_substitute);
|
||||
slim_hidden_proto (cairo_ft_scaled_font_lock_face);
|
||||
slim_hidden_proto (cairo_ft_scaled_font_unlock_face);
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
||||
glitz_find_standard_format (drawable,
|
||||
_glitz_format_from_content (content));
|
||||
if (!gformat) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
||||
0, NULL);
|
||||
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -165,8 +165,10 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
|
||||
return NULL;
|
||||
|
||||
gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
|
||||
if (gboxes == NULL)
|
||||
if (gboxes == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
gboxes[i].x1 = cboxes[i].p1.x;
|
||||
@ -270,12 +272,12 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
|
||||
pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
|
||||
if (!pixels)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
buffer = glitz_buffer_create_for_data (pixels);
|
||||
if (!buffer) {
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* clear out the glitz clip; the clip affects glitz_get_pixels */
|
||||
@ -299,7 +301,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
|
||||
if (box == NULL && n != 0) {
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
|
||||
@ -345,7 +347,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
|
||||
FAIL:
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -428,7 +430,7 @@ _cairo_glitz_surface_set_image (void *abstract_surface,
|
||||
|
||||
buffer = glitz_buffer_create_for_data (data);
|
||||
if (!buffer)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
glitz_set_pixels (surface->surface,
|
||||
x_dst, y_dst,
|
||||
@ -491,10 +493,13 @@ _cairo_glitz_surface_release_dest_image (void *abstract_surfa
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_glitz_surface_set_image (surface, image, 0, 0,
|
||||
image->width, image->height,
|
||||
image_rect->x, image_rect->y);
|
||||
status = _cairo_glitz_surface_set_image (surface, image, 0, 0,
|
||||
image->width, image->height,
|
||||
image_rect->x, image_rect->y);
|
||||
if (status)
|
||||
status = _cairo_surface_set_error (&surface->base, status);
|
||||
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
@ -510,6 +515,7 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
cairo_glitz_surface_t *clone;
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->base.status)
|
||||
return surface->base.status;
|
||||
@ -534,7 +540,7 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
|
||||
image_src->width,
|
||||
image_src->height);
|
||||
if (clone->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return clone->base.status;
|
||||
|
||||
image_extent.x = 0;
|
||||
image_extent.y = 0;
|
||||
@ -547,10 +553,14 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
|
||||
|
||||
_cairo_rectangle_intersect(&extent, &image_extent);
|
||||
|
||||
_cairo_glitz_surface_set_image (clone, image_src,
|
||||
extent.x, extent.y,
|
||||
extent.width, extent.height,
|
||||
extent.x, extent.y);
|
||||
status = _cairo_glitz_surface_set_image (clone, image_src,
|
||||
extent.x, extent.y,
|
||||
extent.width, extent.height,
|
||||
extent.x, extent.y);
|
||||
if (status) {
|
||||
cairo_surface_destroy (&clone->base);
|
||||
return status;
|
||||
}
|
||||
|
||||
*clone_out = &clone->base;
|
||||
|
||||
@ -764,29 +774,28 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
||||
int size1, size2;
|
||||
if (n_params >= INT32_MAX / sizeof (glitz_fixed16_16_t) ||
|
||||
gradient->n_stops >= INT32_MAX / sizeof (unsigned int))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
size1 = n_params * sizeof (glitz_fixed16_16_t);
|
||||
size2 = gradient->n_stops * sizeof (unsigned int);
|
||||
|
||||
if (size1 >= INT32_MAX - size2)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
data = malloc (size1 + size2);
|
||||
}
|
||||
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
params = (glitz_fixed16_16_t *) data;
|
||||
pixels = (unsigned int *)
|
||||
(data + sizeof (glitz_fixed16_16_t) * n_params);
|
||||
|
||||
buffer = glitz_buffer_create_for_data (pixels);
|
||||
if (!buffer)
|
||||
{
|
||||
if (!buffer) {
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
src = (cairo_glitz_surface_t *)
|
||||
@ -797,7 +806,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
||||
{
|
||||
glitz_buffer_destroy (buffer);
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return src->base.status;
|
||||
}
|
||||
|
||||
for (i = 0; i < gradient->n_stops; i++)
|
||||
@ -1158,7 +1167,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||
(cairo_color_t *) color,
|
||||
NULL);
|
||||
if (src->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return src->base.status;
|
||||
|
||||
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
|
||||
|
||||
@ -1277,7 +1286,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return mask->base.status;
|
||||
}
|
||||
|
||||
color.red = color.green = color.blue = color.alpha = 0xffff;
|
||||
@ -1304,7 +1313,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
&attributes);
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
@ -1317,7 +1326,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
&attributes);
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1347,13 +1356,13 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
int stride;
|
||||
|
||||
stride = (width + 3) & -4;
|
||||
data = calloc (stride * height, 1);
|
||||
data = calloc (stride, height);
|
||||
if (!data)
|
||||
{
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
if (src_pattern == &tmp_src_pattern.base)
|
||||
_cairo_pattern_fini (&tmp_src_pattern.base);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* using negative stride */
|
||||
@ -1368,7 +1377,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
{
|
||||
cairo_surface_destroy (&src->base);
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return image->base.status;
|
||||
}
|
||||
|
||||
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
|
||||
@ -1383,12 +1392,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
free (data);
|
||||
cairo_surface_destroy (&image->base);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return mask->base.status;
|
||||
}
|
||||
|
||||
_cairo_glitz_surface_set_image (mask, image, 0, 0, width, height, 0, 0);
|
||||
status = _cairo_glitz_surface_set_image (mask, image,
|
||||
0, 0, width, height, 0, 0);
|
||||
|
||||
cairo_surface_destroy(&image->base);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_glitz_surface_set_attributes (src, &attributes);
|
||||
@ -1438,24 +1451,25 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
||||
{
|
||||
glitz_box_t *box;
|
||||
int n;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->has_clip) {
|
||||
_cairo_region_init (&surface->clip);
|
||||
surface->has_clip = TRUE;
|
||||
}
|
||||
|
||||
if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
status = _cairo_region_copy (&surface->clip, region);
|
||||
if (status) {
|
||||
_cairo_region_fini (&surface->clip);
|
||||
surface->has_clip = FALSE;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return status;
|
||||
}
|
||||
|
||||
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
|
||||
if (box == NULL && n != 0) {
|
||||
_cairo_region_fini (&surface->clip);
|
||||
surface->has_clip = FALSE;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
|
||||
@ -1565,8 +1579,10 @@ _cairo_glitz_area_create (cairo_glitz_root_area_t *root,
|
||||
int n = 4;
|
||||
|
||||
area = malloc (sizeof (cairo_glitz_area_t));
|
||||
if (!area)
|
||||
if (!area) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
area->level = level;
|
||||
area->x = x;
|
||||
@ -1788,7 +1804,7 @@ _cairo_glitz_root_area_init (cairo_glitz_root_area_t *root,
|
||||
|
||||
root->area = _cairo_glitz_area_create (root, 0, 0, 0, width, height);
|
||||
if (!root->area)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1901,7 +1917,7 @@ _cairo_glitz_surface_font_init (cairo_glitz_surface_t *surface,
|
||||
|
||||
font_private = malloc (sizeof (cairo_glitz_surface_font_private_t));
|
||||
if (!font_private)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font_private->surface = glitz_surface_create (drawable, surface_format,
|
||||
GLYPH_CACHE_TEXTURE_SIZE,
|
||||
@ -1987,7 +2003,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
||||
{
|
||||
glyph_private = malloc (sizeof (cairo_glitz_surface_glyph_private_t));
|
||||
if (!glyph_private)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
glyph_private->area = NULL;
|
||||
glyph_private->locked = FALSE;
|
||||
@ -2031,7 +2047,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
||||
if (!buffer)
|
||||
{
|
||||
_cairo_glitz_area_move_out (glyph_private->area);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
cairo_format_get_masks (glyph_surface->format, &bpp, &am, &rm, &gm, &bm);
|
||||
@ -2151,8 +2167,10 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
goto FAIL1;
|
||||
|
||||
data = malloc (size1 + size2);
|
||||
if (!data)
|
||||
if (!data) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL1;
|
||||
}
|
||||
|
||||
scaled_glyphs = (cairo_scaled_glyph_t **) data;
|
||||
vertices = (glitz_float_t *) (data + num_glyphs * sizeof (void *));
|
||||
@ -2440,7 +2458,7 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
|
||||
|
||||
crsurface = malloc (sizeof (cairo_glitz_surface_t));
|
||||
if (crsurface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
||||
@ -62,6 +62,8 @@ cairo_status_t
|
||||
_cairo_gstate_init (cairo_gstate_t *gstate,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
gstate->next = NULL;
|
||||
|
||||
gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
|
||||
@ -93,10 +95,23 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
||||
|
||||
gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
if (gstate->source->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return target ? target->status : CAIRO_STATUS_NULL_POINTER;
|
||||
/* Now that the gstate is fully initialized and ready for the eventual
|
||||
* _cairo_gstate_fini(), we can check for errors (and not worry about
|
||||
* the resource deallocation). */
|
||||
|
||||
if (target == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
|
||||
|
||||
status = target->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = gstate->source->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,8 +146,12 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
|
||||
|
||||
status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
|
||||
if (status)
|
||||
if (status) {
|
||||
_cairo_stroke_style_fini (&gstate->stroke_style);
|
||||
cairo_font_face_destroy (gstate->font_face);
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
return status;
|
||||
}
|
||||
|
||||
gstate->target = cairo_surface_reference (other->target);
|
||||
/* parent_target is always set to NULL; it's only ever set by redirect_target */
|
||||
@ -170,7 +189,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
|
||||
gstate->parent_target = NULL;
|
||||
|
||||
cairo_surface_destroy (gstate->original_target);
|
||||
gstate->target = NULL;
|
||||
gstate->original_target = NULL;
|
||||
|
||||
cairo_pattern_destroy (gstate->source);
|
||||
gstate->source = NULL;
|
||||
@ -207,8 +226,10 @@ _cairo_gstate_clone (cairo_gstate_t *other)
|
||||
assert (other != NULL);
|
||||
|
||||
gstate = malloc (sizeof (cairo_gstate_t));
|
||||
if (gstate == NULL)
|
||||
if (gstate == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = _cairo_gstate_init_copy (gstate, other);
|
||||
if (status) {
|
||||
@ -233,10 +254,8 @@ _cairo_gstate_save (cairo_gstate_t **gstate)
|
||||
cairo_gstate_t *top;
|
||||
|
||||
top = _cairo_gstate_clone (*gstate);
|
||||
|
||||
if (top == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (top == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
top->next = *gstate;
|
||||
*gstate = top;
|
||||
@ -256,10 +275,8 @@ _cairo_gstate_restore (cairo_gstate_t **gstate)
|
||||
cairo_gstate_t *top;
|
||||
|
||||
top = *gstate;
|
||||
|
||||
if (top->next == NULL) {
|
||||
return CAIRO_STATUS_INVALID_RESTORE;
|
||||
}
|
||||
if (top->next == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
|
||||
|
||||
*gstate = top->next;
|
||||
|
||||
@ -533,7 +550,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
|
||||
gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
|
||||
if (gstate->stroke_style.dash == NULL) {
|
||||
gstate->stroke_style.num_dashes = 0;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
memcpy (gstate->stroke_style.dash, dash, gstate->stroke_style.num_dashes * sizeof (double));
|
||||
@ -541,12 +558,12 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
|
||||
dash_total = 0.0;
|
||||
for (i = 0; i < gstate->stroke_style.num_dashes; i++) {
|
||||
if (gstate->stroke_style.dash[i] < 0)
|
||||
return CAIRO_STATUS_INVALID_DASH;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_DASH);
|
||||
dash_total += gstate->stroke_style.dash[i];
|
||||
}
|
||||
|
||||
if (dash_total == 0.0)
|
||||
return CAIRO_STATUS_INVALID_DASH;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_DASH);
|
||||
|
||||
/* A single dash value indicate symmetric repeating, so the total
|
||||
* is twice as long. */
|
||||
@ -606,6 +623,9 @@ _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
if (! (tx * tx >= 0.) || ! (ty * ty >= 0.)) /* check for NaNs */
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_gstate_unset_scaled_font (gstate);
|
||||
|
||||
cairo_matrix_init_translate (&tmp, tx, ty);
|
||||
@ -622,8 +642,10 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
if (sx == 0 || sy == 0)
|
||||
return CAIRO_STATUS_INVALID_MATRIX;
|
||||
if (sx * sy == 0.) /* either sx or sy is 0, or det == 0 due to underflow */
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
if (! (sx * sx > 0.) || ! (sy * sy > 0.)) /* check for NaNs */
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_gstate_unset_scaled_font (gstate);
|
||||
|
||||
@ -641,6 +663,12 @@ _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
if (angle == 0.)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (! (angle * angle >= 0.)) /* check for NaNs */
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_gstate_unset_scaled_font (gstate);
|
||||
|
||||
cairo_matrix_init_rotate (&tmp, angle);
|
||||
@ -996,7 +1024,7 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate,
|
||||
double y,
|
||||
cairo_bool_t *inside_ret)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
|
||||
if (gstate->stroke_style.line_width <= 0.0) {
|
||||
@ -1062,7 +1090,7 @@ _cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
||||
double y,
|
||||
cairo_bool_t *inside_ret)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
|
||||
_cairo_gstate_user_to_backend (gstate, &x, &y);
|
||||
@ -1269,11 +1297,9 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate,
|
||||
return font_face->status;
|
||||
|
||||
status = _cairo_gstate_set_font_face (gstate, font_face);
|
||||
if (status)
|
||||
return status;
|
||||
cairo_font_face_destroy (font_face);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1291,6 +1317,9 @@ cairo_status_t
|
||||
_cairo_gstate_set_font_matrix (cairo_gstate_t *gstate,
|
||||
const cairo_matrix_t *matrix)
|
||||
{
|
||||
if (! _cairo_matrix_is_invertible (matrix))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_gstate_unset_scaled_font (gstate);
|
||||
|
||||
gstate->font_matrix = *matrix;
|
||||
@ -1557,7 +1586,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
||||
cairo_glyph_t *transformed_glyphs;
|
||||
cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
|
||||
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
|
||||
@ -1574,7 +1602,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
||||
} else {
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
|
||||
@ -1619,14 +1647,16 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
||||
else
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
|
||||
transformed_glyphs);
|
||||
|
||||
CAIRO_MUTEX_LOCK (gstate->scaled_font->mutex);
|
||||
status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
|
||||
transformed_glyphs, num_glyphs,
|
||||
path);
|
||||
CAIRO_MUTEX_UNLOCK (gstate->scaled_font->mutex);
|
||||
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
free (transformed_glyphs);
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#ifndef CAIRO_HASH_PRIVATE_H
|
||||
#define CAIRO_HASH_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
/* XXX: I'd like this file to be self-contained in terms of
|
||||
|
||||
@ -149,8 +149,10 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
hash_table = malloc (sizeof (cairo_hash_table_t));
|
||||
if (hash_table == NULL)
|
||||
if (hash_table == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash_table->keys_equal = keys_equal;
|
||||
|
||||
@ -159,6 +161,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
|
||||
hash_table->entries = calloc (hash_table->arrangement->size,
|
||||
sizeof(cairo_hash_entry_t *));
|
||||
if (hash_table->entries == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
free (hash_table);
|
||||
return NULL;
|
||||
}
|
||||
@ -329,7 +332,7 @@ _cairo_hash_table_resize (cairo_hash_table_t *hash_table)
|
||||
new_size = tmp.arrangement->size;
|
||||
tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
|
||||
if (tmp.entries == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
for (i = 0; i < hash_table->arrangement->size; ++i) {
|
||||
if (ENTRY_IS_LIVE (hash_table->entries[i])) {
|
||||
|
||||
@ -63,8 +63,10 @@ _cairo_hull_create (cairo_pen_vertex_t *vertices, int num_vertices)
|
||||
vertices[0].point = tmp;
|
||||
|
||||
hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
|
||||
if (hull == NULL)
|
||||
if (hull == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
hull[i].point = vertices[i].point;
|
||||
@ -140,7 +142,7 @@ _cairo_hull_next_valid (cairo_hull_t *hull, int num_hull, int index)
|
||||
return index;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
static void
|
||||
_cairo_hull_eliminate_concave (cairo_hull_t *hull, int num_hull)
|
||||
{
|
||||
int i, j, k;
|
||||
@ -157,7 +159,7 @@ _cairo_hull_eliminate_concave (cairo_hull_t *hull, int num_hull)
|
||||
/* Is the angle formed by ij and jk concave? */
|
||||
if (_cairo_slope_compare (&slope_ij, &slope_jk) >= 0) {
|
||||
if (i == k)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return;
|
||||
hull[j].discard = 1;
|
||||
j = i;
|
||||
i = _cairo_hull_prev_valid (hull, num_hull, j);
|
||||
@ -167,11 +169,9 @@ _cairo_hull_eliminate_concave (cairo_hull_t *hull, int num_hull)
|
||||
k = _cairo_hull_next_valid (hull, num_hull, j);
|
||||
}
|
||||
} while (j != 0);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
static void
|
||||
_cairo_hull_to_pen (cairo_hull_t *hull, cairo_pen_vertex_t *vertices, int *num_vertices)
|
||||
{
|
||||
int i, j = 0;
|
||||
@ -183,8 +183,6 @@ _cairo_hull_to_pen (cairo_hull_t *hull, cairo_pen_vertex_t *vertices, int *num_v
|
||||
}
|
||||
|
||||
*num_vertices = j;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Given a set of vertices, compute the convex hull using the Graham
|
||||
|
||||
@ -42,7 +42,7 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_INVALID_FORMAT, /* status */
|
||||
FALSE, /* finished */
|
||||
{ 0, /* size */
|
||||
@ -84,6 +84,53 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
|
||||
0, /* depth */
|
||||
NULL /* pixman_image */
|
||||
};
|
||||
static const cairo_image_surface_t _cairo_image_surface_nil_invalid_content = {
|
||||
{
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_INVALID_CONTENT, /* status */
|
||||
FALSE, /* finished */
|
||||
{ 0, /* size */
|
||||
0, /* num_elements */
|
||||
0, /* element_size */
|
||||
NULL, /* elements */
|
||||
}, /* user_data */
|
||||
{ 1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0
|
||||
}, /* device_transform */
|
||||
{ 1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0
|
||||
}, /* device_transform_inverse */
|
||||
0.0, /* x_resolution */
|
||||
0.0, /* y_resolution */
|
||||
0.0, /* x_fallback_resolution */
|
||||
0.0, /* y_fallback_resolution */
|
||||
NULL, /* clip */
|
||||
0, /* next_clip_serial */
|
||||
0, /* current_clip_serial */
|
||||
FALSE, /* is_snapshot */
|
||||
FALSE, /* has_font_options */
|
||||
{ CAIRO_ANTIALIAS_DEFAULT,
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT,
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_METRICS_DEFAULT
|
||||
} /* font_options */
|
||||
}, /* base */
|
||||
PIXMAN_a8r8g8b8, /* pixman_format */
|
||||
CAIRO_FORMAT_ARGB32, /* format */
|
||||
NULL, /* data */
|
||||
FALSE, /* owns_data */
|
||||
FALSE, /* has_clip */
|
||||
0, /* width */
|
||||
0, /* height */
|
||||
0, /* stride */
|
||||
0, /* depth */
|
||||
NULL /* pixman_image */
|
||||
};
|
||||
|
||||
static cairo_format_t
|
||||
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
|
||||
@ -167,7 +214,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
|
||||
surface = malloc (sizeof (cairo_image_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -386,7 +433,7 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data,
|
||||
(uint32_t *) data, stride);
|
||||
|
||||
if (pixman_image == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -424,11 +471,10 @@ cairo_image_surface_create (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_code_t pixman_format;
|
||||
|
||||
if (! CAIRO_FORMAT_VALID (format)) {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
|
||||
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
|
||||
}
|
||||
|
||||
@ -436,8 +482,6 @@ cairo_image_surface_create (cairo_format_t format,
|
||||
|
||||
return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format,
|
||||
width, height, -1);
|
||||
|
||||
return surface;
|
||||
}
|
||||
slim_hidden_def (cairo_image_surface_create);
|
||||
|
||||
@ -446,8 +490,10 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (! CAIRO_CONTENT_VALID (content))
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
if (! CAIRO_CONTENT_VALID (content)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
|
||||
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
|
||||
}
|
||||
|
||||
return cairo_image_surface_create (_cairo_format_from_content (content),
|
||||
width, height);
|
||||
@ -492,8 +538,13 @@ cairo_image_surface_create_for_data (unsigned char *data,
|
||||
{
|
||||
pixman_format_code_t pixman_format;
|
||||
|
||||
if (! CAIRO_FORMAT_VALID (format))
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
/* XXX pixman does not support images with arbitrary strides and
|
||||
* attempting to create such surfaces will failure but we will interpret
|
||||
* such failure as CAIRO_STATUS_NO_MEMORY. */
|
||||
if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0) {
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
|
||||
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
|
||||
}
|
||||
|
||||
pixman_format = _cairo_format_to_pixman_format_code (format);
|
||||
|
||||
@ -509,8 +560,10 @@ _cairo_image_surface_create_for_data_with_content (unsigned char *data,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
if (! CAIRO_CONTENT_VALID (content))
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
if (! CAIRO_CONTENT_VALID (content)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
|
||||
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
|
||||
}
|
||||
|
||||
return cairo_image_surface_create_for_data (data,
|
||||
_cairo_format_from_content (content),
|
||||
@ -535,7 +588,7 @@ cairo_image_surface_get_data (cairo_surface_t *surface)
|
||||
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
if (!_cairo_surface_is_image (surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -558,7 +611,7 @@ cairo_image_surface_get_format (cairo_surface_t *surface)
|
||||
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
if (!_cairo_surface_is_image (surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -581,7 +634,7 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
|
||||
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
if (!_cairo_surface_is_image (surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -603,7 +656,7 @@ cairo_image_surface_get_height (cairo_surface_t *surface)
|
||||
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
if (!_cairo_surface_is_image (surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -631,7 +684,7 @@ cairo_image_surface_get_stride (cairo_surface_t *surface)
|
||||
cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
if (!_cairo_surface_is_image (surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -783,7 +836,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
|
||||
_cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
|
||||
|
||||
if (!pixman_image_set_transform (surface->pixman_image, &pixman_transform))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1007,7 +1060,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
if (num_rects > ARRAY_LENGTH(stack_rects)) {
|
||||
pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
|
||||
if (pixman_rects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
@ -1022,8 +1075,9 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
surface->pixman_image,
|
||||
&pixman_color,
|
||||
num_rects,
|
||||
pixman_rects))
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
pixman_rects)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (pixman_rects != stack_rects)
|
||||
free (pixman_rects);
|
||||
@ -1069,7 +1123,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (num_traps > ARRAY_LENGTH(stack_traps)) {
|
||||
pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
|
||||
if (pixman_traps == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
@ -1142,16 +1196,16 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
}
|
||||
|
||||
/* The image must be initially transparent */
|
||||
mask_data = calloc (1, mask_stride * height);
|
||||
mask_data = calloc (mask_stride, height);
|
||||
if (mask_data == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
|
||||
mask = pixman_image_create_bits (format, width, height,
|
||||
mask_data, mask_stride);
|
||||
if (mask == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_IMAGE_DATA;
|
||||
}
|
||||
|
||||
@ -1199,7 +1253,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
|
||||
|
||||
if (!pixman_image_set_clip_region (surface->pixman_image, ®ion->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
surface->has_clip = region != NULL;
|
||||
|
||||
@ -1297,6 +1351,7 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
|
||||
cairo_format_t format)
|
||||
{
|
||||
cairo_image_surface_t *clone;
|
||||
cairo_status_t status;
|
||||
cairo_t *cr;
|
||||
double x, y;
|
||||
|
||||
@ -1312,7 +1367,13 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
|
||||
cairo_set_source_surface (cr, &surface->base, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
status = cairo_status (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
if (status) {
|
||||
cairo_surface_destroy (&clone->base);
|
||||
return (cairo_image_surface_t *) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
|
||||
buf->data = malloc (size);
|
||||
if (buf->data == NULL) {
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -93,11 +93,15 @@ _lzw_buf_grow (lzw_buf_t *buf)
|
||||
if (buf->status)
|
||||
return buf->status;
|
||||
|
||||
new_data = realloc (buf->data, new_size);
|
||||
new_data = NULL;
|
||||
/* check for integer overflow */
|
||||
if (new_size / 2 == buf->data_size)
|
||||
new_data = realloc (buf->data, new_size);
|
||||
|
||||
if (new_data == NULL) {
|
||||
free (buf->data);
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return buf->status;
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @a*@size memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves much like
|
||||
* calloc(), except that the returned memory is not set to zero.
|
||||
* The memory should be freed using free().
|
||||
@ -75,13 +75,35 @@
|
||||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
_cairo_malloc((unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_realloc_ab:
|
||||
* @ptr: original pointer to block of memory to be resized
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Reallocates @ptr a block of @n*@size memory using realloc(), taking
|
||||
* care to not overflow when doing the multiplication. The memory
|
||||
* should be freed using free().
|
||||
*
|
||||
* @size should be a constant so that the compiler can optimize
|
||||
* out a constant division.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of realloc() failure or overflow (whereupon the original block
|
||||
* of memory * is left untouched).
|
||||
*/
|
||||
|
||||
#define _cairo_realloc_ab(ptr, a, size) \
|
||||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
realloc(ptr, (unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_malloc_abc:
|
||||
* @a: first factor of number of elements to allocate
|
||||
* @n: first factor of number of elements to allocate
|
||||
* @b: second factor of number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @a*@b*@size memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@b*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
@ -103,7 +125,7 @@
|
||||
* @size: size of each element
|
||||
* @k: additional size to allocate
|
||||
*
|
||||
* Allocates @a*@ksize+@k memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@ksize+@k memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the arithmetic. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
|
||||
@ -473,11 +473,11 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
|
||||
_cairo_matrix_compute_determinant (matrix, &det);
|
||||
|
||||
if (det == 0)
|
||||
return CAIRO_STATUS_INVALID_MATRIX;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
/* this weird construct is for detecting NaNs */
|
||||
if (! (det * det > 0.))
|
||||
return CAIRO_STATUS_INVALID_MATRIX;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
_cairo_matrix_compute_adjoint (matrix);
|
||||
_cairo_matrix_scalar_multiply (matrix, 1 / det);
|
||||
@ -486,6 +486,16 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
|
||||
}
|
||||
slim_hidden_def(cairo_matrix_invert);
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
|
||||
{
|
||||
double det;
|
||||
|
||||
_cairo_matrix_compute_determinant (matrix, &det);
|
||||
|
||||
return det != 0. && det * det > 0.;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix,
|
||||
double *det)
|
||||
|
||||
@ -61,7 +61,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
CAIRO_META_REGION_ALL,
|
||||
CAIRO_META_REGION_NATIVE,
|
||||
CAIRO_META_REGION_IMAGE_FALLBACK,
|
||||
CAIRO_META_REGION_IMAGE_FALLBACK
|
||||
} cairo_meta_region_type_t;
|
||||
|
||||
typedef struct _cairo_command_header {
|
||||
|
||||
@ -85,7 +85,7 @@ _cairo_meta_surface_create (cairo_content_t content,
|
||||
|
||||
meta = malloc (sizeof (cairo_meta_surface_t));
|
||||
if (meta == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ _cairo_meta_surface_paint (void *abstract_surface,
|
||||
|
||||
command = malloc (sizeof (cairo_command_paint_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_PAINT;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -294,7 +294,7 @@ _cairo_meta_surface_mask (void *abstract_surface,
|
||||
|
||||
command = malloc (sizeof (cairo_command_mask_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_MASK;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -340,7 +340,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
|
||||
|
||||
command = malloc (sizeof (cairo_command_stroke_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_STROKE;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -395,7 +395,7 @@ _cairo_meta_surface_fill (void *abstract_surface,
|
||||
|
||||
command = malloc (sizeof (cairo_command_fill_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_FILL;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -442,7 +442,7 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
|
||||
|
||||
command = malloc (sizeof (cairo_command_show_glyphs_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_SHOW_GLYPHS;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -454,7 +454,7 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
|
||||
|
||||
command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (command->glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
||||
@ -476,7 +476,7 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -500,7 +500,7 @@ _cairo_meta_surface_snapshot (void *abstract_other)
|
||||
|
||||
meta = malloc (sizeof (cairo_meta_surface_t));
|
||||
if (meta == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
||||
|
||||
command = malloc (sizeof (cairo_command_intersect_clip_path_t));
|
||||
if (command == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
@ -667,10 +667,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
|
||||
cairo_matrix_t *device_transform = &target->device_transform;
|
||||
cairo_path_fixed_t path_copy, *dev_path;
|
||||
double tolerance_multiplier = _cairo_matrix_transformed_circle_major_axis (device_transform, 1.0);
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (target->status)
|
||||
return _cairo_surface_set_error (surface, target->status);
|
||||
|
||||
meta = (cairo_meta_surface_t *) surface;
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
@ -736,7 +740,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
&command->stroke.style,
|
||||
&dev_ctm,
|
||||
&dev_ctm_inverse,
|
||||
command->stroke.tolerance,
|
||||
command->stroke.tolerance * tolerance_multiplier,
|
||||
command->stroke.antialias);
|
||||
break;
|
||||
}
|
||||
@ -768,7 +772,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
command->fill.op,
|
||||
&command->fill.source.base,
|
||||
command->fill.fill_rule,
|
||||
command->fill.tolerance,
|
||||
command->fill.tolerance * tolerance_multiplier,
|
||||
command->fill.antialias,
|
||||
dev_path,
|
||||
stroke_command->stroke.op,
|
||||
@ -776,7 +780,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
&stroke_command->stroke.style,
|
||||
&dev_ctm,
|
||||
&dev_ctm_inverse,
|
||||
stroke_command->stroke.tolerance,
|
||||
stroke_command->stroke.tolerance * tolerance_multiplier,
|
||||
stroke_command->stroke.antialias);
|
||||
i++;
|
||||
} else
|
||||
@ -785,7 +789,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
&command->fill.source.base,
|
||||
dev_path,
|
||||
command->fill.fill_rule,
|
||||
command->fill.tolerance,
|
||||
command->fill.tolerance * tolerance_multiplier,
|
||||
command->fill.antialias);
|
||||
break;
|
||||
}
|
||||
@ -798,7 +802,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
if (has_device_transform) {
|
||||
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (dev_glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
@ -828,7 +832,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
else
|
||||
status = _cairo_clip_clip (&clip, dev_path,
|
||||
command->intersect_clip_path.fill_rule,
|
||||
command->intersect_clip_path.tolerance,
|
||||
command->intersect_clip_path.tolerance * tolerance_multiplier,
|
||||
command->intersect_clip_path.antialias,
|
||||
target);
|
||||
assert (status == 0);
|
||||
@ -860,7 +864,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
|
||||
_cairo_clip_reset (&clip);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
||||
@ -46,6 +46,9 @@ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex);
|
||||
CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex);
|
||||
#endif
|
||||
|
||||
#if !defined (CAIRO_HAS_ATOMIC_OPS) || defined (CAIRO_ATOMIC_OP_NEEDS_MEMORY_BARRIER)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex);
|
||||
#endif
|
||||
|
||||
/* Undefine, to err on unintended inclusion */
|
||||
#undef CAIRO_MUTEX_DECLARE
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
|
||||
#include <cairo-features.h>
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-mutex-type-private.h"
|
||||
|
||||
/* Only the following three are mandatory at this point */
|
||||
|
||||
@ -473,7 +473,7 @@ _cairo_os2_surface_acquire_source_image (void *abstract_surfac
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
|
||||
@ -529,7 +529,7 @@ _cairo_os2_surface_acquire_dest_image (void *abstract_surfac
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
|
||||
@ -637,7 +637,7 @@ _cairo_os2_surface_get_extents (void *abstract_surface,
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
rectangle->x = 0;
|
||||
@ -773,14 +773,14 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
if ((new_width <= 0) ||
|
||||
(new_height <= 0))
|
||||
{
|
||||
/* Invalid size! */
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Allocate memory for new stuffs */
|
||||
@ -789,7 +789,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
/* Not enough memory for the pixels!
|
||||
* Everything remains the same!
|
||||
*/
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* This is possibly not needed, malloc'd space is usually
|
||||
@ -812,7 +812,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
* Everything remains the same!
|
||||
*/
|
||||
free (pchNewPixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Okay, new memory allocated, so it's time to swap old buffers
|
||||
@ -824,7 +824,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
*/
|
||||
cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
|
||||
free (pchNewPixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* We have to make sure that we won't destroy a surface which
|
||||
@ -840,7 +840,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
/* Either timeout or something wrong... Exit. */
|
||||
cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
|
||||
free (pchNewPixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
/* Okay, grab mutex and check counter again! */
|
||||
if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT)
|
||||
@ -851,7 +851,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
||||
*/
|
||||
cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
|
||||
free (pchNewPixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -949,7 +949,7 @@ _cairo_os2_surface_finish (void *abstract_surface)
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
|
||||
@ -1042,7 +1042,7 @@ _cairo_os2_surface_mark_dirty_rectangle (void *surface,
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
/* Get mutex, we'll work with the pixel array! */
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#ifndef CAIRO_OUTPUT_STREAM_PRIVATE_H
|
||||
#define CAIRO_OUTPUT_STREAM_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
typedef cairo_status_t (*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream,
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
cairo_private void
|
||||
void
|
||||
_cairo_output_stream_init (cairo_output_stream_t *stream,
|
||||
cairo_output_stream_write_func_t write_func,
|
||||
cairo_output_stream_close_func_t close_func)
|
||||
@ -58,7 +58,7 @@ _cairo_output_stream_init (cairo_output_stream_t *stream,
|
||||
stream->closed = FALSE;
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_status_t
|
||||
_cairo_output_stream_fini (cairo_output_stream_t *stream)
|
||||
{
|
||||
return _cairo_output_stream_close (stream);
|
||||
@ -119,8 +119,10 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_output_stream_with_closure_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_output_stream_with_closure_t));
|
||||
if (stream == NULL)
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, closure_write, closure_close);
|
||||
stream->write_func = write_func;
|
||||
@ -162,7 +164,13 @@ _cairo_output_stream_destroy (cairo_output_stream_t *stream)
|
||||
cairo_status_t status;
|
||||
|
||||
if (stream == NULL)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
|
||||
|
||||
if (stream == &_cairo_output_stream_nil ||
|
||||
stream == &_cairo_output_stream_nil_write_error)
|
||||
{
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
status = _cairo_output_stream_fini (stream);
|
||||
free (stream);
|
||||
@ -207,6 +215,8 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
}
|
||||
}
|
||||
|
||||
#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
|
||||
|
||||
/* Format a double in a locale independent way and trim trailing
|
||||
* zeros. Based on code from Alex Larson <alexl@redhat.com>.
|
||||
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
|
||||
@ -223,18 +233,53 @@ _cairo_dtostr (char *buffer, size_t size, double d)
|
||||
int decimal_point_len;
|
||||
char *p;
|
||||
int decimal_len;
|
||||
int num_zeros, decimal_digits;
|
||||
|
||||
/* Omit the minus sign from negative zero. */
|
||||
if (d == 0.0)
|
||||
d = 0.0;
|
||||
|
||||
snprintf (buffer, size, "%f", d);
|
||||
|
||||
locale_data = localeconv ();
|
||||
decimal_point = locale_data->decimal_point;
|
||||
decimal_point_len = strlen (decimal_point);
|
||||
|
||||
assert (decimal_point_len != 0);
|
||||
|
||||
/* Using "%f" to print numbers less than 0.1 will result in
|
||||
* reduced precision due to the default 6 digits after the
|
||||
* decimal point.
|
||||
*
|
||||
* For numbers is < 0.1, we print with maximum precision and count
|
||||
* the number of zeros between the decimal point and the first
|
||||
* significant digit. We then print the number again with the
|
||||
* number of decimal places that gives us the required number of
|
||||
* significant digits. This ensures the number is correctly
|
||||
* rounded.
|
||||
*/
|
||||
if (fabs (d) >= 0.1) {
|
||||
snprintf (buffer, size, "%f", d);
|
||||
} else {
|
||||
snprintf (buffer, size, "%.18f", d);
|
||||
p = buffer;
|
||||
|
||||
if (*p == '+' || *p == '-')
|
||||
p++;
|
||||
|
||||
while (isdigit (*p))
|
||||
p++;
|
||||
|
||||
if (strncmp (p, decimal_point, decimal_point_len) == 0)
|
||||
p += decimal_point_len;
|
||||
|
||||
num_zeros = 0;
|
||||
while (*p++ == '0')
|
||||
num_zeros++;
|
||||
|
||||
decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
|
||||
|
||||
if (decimal_digits < 18)
|
||||
snprintf (buffer, size, "%.*f", decimal_digits, d);
|
||||
}
|
||||
p = buffer;
|
||||
|
||||
if (*p == '+' || *p == '-')
|
||||
@ -432,7 +477,7 @@ stdio_write (cairo_output_stream_t *base,
|
||||
stdio_stream_t *stream = (stdio_stream_t *) base;
|
||||
|
||||
if (fwrite (data, 1, length, stream->file) != length)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -445,7 +490,7 @@ stdio_flush (cairo_output_stream_t *base)
|
||||
fflush (stream->file);
|
||||
|
||||
if (ferror (stream->file))
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -468,12 +513,16 @@ _cairo_output_stream_create_for_file (FILE *file)
|
||||
{
|
||||
stdio_stream_t *stream;
|
||||
|
||||
if (file == NULL)
|
||||
if (file == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
|
||||
}
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL)
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, stdio_write, stdio_flush);
|
||||
stream->file = file;
|
||||
@ -488,12 +537,15 @@ _cairo_output_stream_create_for_filename (const char *filename)
|
||||
FILE *file;
|
||||
|
||||
file = fopen (filename, "wb");
|
||||
if (file == NULL)
|
||||
if (file == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
|
||||
}
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL) {
|
||||
fclose (file);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
@ -534,8 +586,10 @@ _cairo_memory_stream_create (void)
|
||||
memory_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof *stream);
|
||||
if (stream == NULL)
|
||||
if (stream == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
|
||||
}
|
||||
|
||||
_cairo_output_stream_init (&stream->base, memory_write, memory_close);
|
||||
_cairo_array_init (&stream->array, 1);
|
||||
@ -549,6 +603,14 @@ _cairo_memory_stream_copy (cairo_output_stream_t *base,
|
||||
{
|
||||
memory_stream_t *stream = (memory_stream_t *) base;
|
||||
|
||||
if (dest->status)
|
||||
return;
|
||||
|
||||
if (base->status) {
|
||||
dest->status = base->status;
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_output_stream_write (dest,
|
||||
_cairo_array_index (&stream->array, 0),
|
||||
_cairo_array_num_elements (&stream->array));
|
||||
|
||||
@ -59,6 +59,14 @@ struct _cairo_paginated_surface_backend {
|
||||
void
|
||||
(*set_paginated_mode) (void *surface,
|
||||
cairo_paginated_mode_t mode);
|
||||
|
||||
/* Optional. Specifies the smallest box that encloses all objects
|
||||
* on the page. Will be called at the end of the ANALYZE phase but
|
||||
* before the mode is changed to RENDER.
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*set_bounding_box) (void *surface,
|
||||
cairo_box_t *bbox);
|
||||
};
|
||||
|
||||
/* A cairo_paginated_surface provides a very convenient wrapper that
|
||||
@ -95,11 +103,14 @@ struct _cairo_paginated_surface_backend {
|
||||
* from each operation). This analysis stage is used to decide which
|
||||
* operations will require fallbacks.
|
||||
*
|
||||
* 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
|
||||
* 4. Calls set_bounding_box to provide the target surface with the
|
||||
* tight bounding box of the page.
|
||||
*
|
||||
* 5. Replays a subset of the meta-surface operations to the target surface
|
||||
* 5. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
|
||||
*
|
||||
* 6. Replays the remaining operations to an image surface, sets an
|
||||
* 6. Replays a subset of the meta-surface operations to the target surface
|
||||
*
|
||||
* 7. Replays the remaining operations to an image surface, sets an
|
||||
* appropriate clip on the target, then paints the resulting image
|
||||
* surface to the target.
|
||||
*
|
||||
@ -114,7 +125,7 @@ struct _cairo_paginated_surface_backend {
|
||||
*
|
||||
* NOTE: The paginated surface layer assumes that the target surface
|
||||
* is "blank" by default at the beginning of each page, without any
|
||||
* need for an explicit erasea operation, (as opposed to an image
|
||||
* need for an explicit erase operation, (as opposed to an image
|
||||
* surface, for example, which might have uninitialized content
|
||||
* originally). As such, it optimizes away CLEAR operations that
|
||||
* happen at the beginning of each page---the target surface will not
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
|
||||
const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
static const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface);
|
||||
@ -76,8 +76,10 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_paginated_surface_t *surface;
|
||||
|
||||
surface = malloc (sizeof (cairo_paginated_surface_t));
|
||||
if (surface == NULL)
|
||||
if (surface == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
|
||||
content);
|
||||
@ -106,7 +108,6 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
FAIL_CLEANUP_SURFACE:
|
||||
free (surface);
|
||||
FAIL:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -129,11 +130,12 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface)
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *paginated_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
assert (_cairo_surface_is_paginated (surface));
|
||||
|
||||
@ -145,8 +147,9 @@ _cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
cairo_surface_destroy (paginated_surface->meta);
|
||||
paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
|
||||
width, height);
|
||||
if (cairo_surface_status (paginated_surface->meta))
|
||||
return cairo_surface_status (paginated_surface->meta);
|
||||
status = cairo_surface_status (paginated_surface->meta);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -284,22 +287,33 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||
cairo_status_t status;
|
||||
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
|
||||
|
||||
if (surface->target->status)
|
||||
return surface->target->status;
|
||||
|
||||
analysis = _cairo_analysis_surface_create (surface->target,
|
||||
surface->width, surface->height);
|
||||
if (analysis == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
|
||||
status = _cairo_meta_surface_replay_and_create_regions (surface->meta, analysis);
|
||||
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
|
||||
|
||||
if (status || analysis->status) {
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = analysis->status;
|
||||
cairo_surface_destroy (analysis);
|
||||
return status;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (surface->backend->set_bounding_box) {
|
||||
cairo_box_t bbox;
|
||||
|
||||
_cairo_analysis_surface_get_bounding_box (analysis, &bbox);
|
||||
status = surface->backend->set_bounding_box (surface->target, &bbox);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
|
||||
|
||||
/* Finer grained fallbacks are currently only supported for some
|
||||
* surface types */
|
||||
switch (surface->target->type) {
|
||||
@ -328,7 +342,7 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||
surface->target,
|
||||
CAIRO_META_REGION_NATIVE);
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (has_page_fallback)
|
||||
@ -341,7 +355,7 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||
box.p2.y = surface->height;
|
||||
status = _paint_fallback_image (surface, &box);
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (has_finegrained_fallback)
|
||||
@ -357,34 +371,39 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||
CAIRO_GSTATE_TOLERANCE_DEFAULT,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
|
||||
region = _cairo_analysis_surface_get_unsupported (analysis);
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
goto FAIL;
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
status = _paint_fallback_image (surface, &boxes[i]);
|
||||
if (status) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return status;
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
}
|
||||
|
||||
FAIL:
|
||||
cairo_surface_destroy (analysis);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface->target, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_start_page (cairo_paginated_surface_t *surface)
|
||||
{
|
||||
if (surface->target->status)
|
||||
return surface->target->status;
|
||||
|
||||
if (! surface->backend->start_page)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return (surface->backend->start_page) (surface->target);
|
||||
return _cairo_surface_set_error (surface->target,
|
||||
surface->backend->start_page (surface->target));
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -431,15 +450,18 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (cairo_surface_status (surface->meta))
|
||||
return cairo_surface_status (surface->meta);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (surface->content,
|
||||
surface->width, surface->height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
return cairo_surface_status (surface->meta);
|
||||
surface->width,
|
||||
surface->height);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
surface->page_num++;
|
||||
surface->page_is_blank = TRUE;
|
||||
@ -631,7 +653,7 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
||||
#endif
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
static const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
_cairo_paginated_surface_create_similar,
|
||||
_cairo_paginated_surface_finish,
|
||||
|
||||
@ -214,7 +214,7 @@ static cairo_int_status_t
|
||||
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_path_buf_t *buf = path->buf_head;
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
int final;
|
||||
|
||||
/* Ensure the path has the operators we expect for a rectangular path.
|
||||
|
||||
@ -46,18 +46,24 @@ enum cairo_path_op {
|
||||
typedef char cairo_path_op_t;
|
||||
|
||||
/* make cairo_path_fixed fit a 512 bytes. about 50 items */
|
||||
#define CAIRO_PATH_BUF_SIZE ((512 - 12 * sizeof (void*)) \
|
||||
/ (sizeof (cairo_point_t) + sizeof (cairo_path_op_t)))
|
||||
#define CAIRO_PATH_BUF_SIZE ((512 - 4 * sizeof (void*) - sizeof (cairo_path_buf_t)) \
|
||||
/ (2 * sizeof (cairo_point_t) + sizeof (cairo_path_op_t)))
|
||||
|
||||
typedef struct _cairo_path_buf {
|
||||
struct _cairo_path_buf *next, *prev;
|
||||
int buf_size;
|
||||
int num_ops;
|
||||
int num_points;
|
||||
|
||||
cairo_path_op_t op[CAIRO_PATH_BUF_SIZE];
|
||||
cairo_point_t points[CAIRO_PATH_BUF_SIZE];
|
||||
|
||||
cairo_path_op_t *op;
|
||||
cairo_point_t *points;
|
||||
} cairo_path_buf_t;
|
||||
typedef struct _cairo_path_buf_fixed {
|
||||
cairo_path_buf_t base;
|
||||
|
||||
cairo_path_op_t op[CAIRO_PATH_BUF_SIZE];
|
||||
cairo_point_t points[2 * CAIRO_PATH_BUF_SIZE];
|
||||
} cairo_path_buf_fixed_t;
|
||||
|
||||
struct _cairo_path_fixed {
|
||||
cairo_point_t last_move_point;
|
||||
@ -65,8 +71,8 @@ struct _cairo_path_fixed {
|
||||
unsigned int has_current_point : 1;
|
||||
unsigned int has_curve_to : 1;
|
||||
|
||||
cairo_path_buf_t *buf_tail;
|
||||
cairo_path_buf_t buf_head[1];
|
||||
cairo_path_buf_t *buf_tail;
|
||||
cairo_path_buf_fixed_t buf_head;
|
||||
};
|
||||
|
||||
#endif /* CAIRO_PATH_FIXED_PRIVATE_H */
|
||||
|
||||
@ -52,7 +52,7 @@ _cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
cairo_path_buf_t *buf);
|
||||
|
||||
static cairo_path_buf_t *
|
||||
_cairo_path_buf_create (void);
|
||||
_cairo_path_buf_create (int buf_size);
|
||||
|
||||
static void
|
||||
_cairo_path_buf_destroy (cairo_path_buf_t *buf);
|
||||
@ -69,12 +69,15 @@ _cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
void
|
||||
_cairo_path_fixed_init (cairo_path_fixed_t *path)
|
||||
{
|
||||
path->buf_head->next = NULL;
|
||||
path->buf_head->prev = NULL;
|
||||
path->buf_tail = path->buf_head;
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
|
||||
path->buf_head->num_ops = 0;
|
||||
path->buf_head->num_points = 0;
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
path->buf_head.base.buf_size = CAIRO_PATH_BUF_SIZE;
|
||||
path->buf_head.base.op = path->buf_head.op;
|
||||
path->buf_head.base.points = path->buf_head.points;
|
||||
|
||||
path->current_point.x = 0;
|
||||
path->current_point.y = 0;
|
||||
@ -90,27 +93,34 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
cairo_path_buf_t *buf, *other_buf;
|
||||
|
||||
_cairo_path_fixed_init (path);
|
||||
|
||||
path->current_point = other->current_point;
|
||||
path->has_current_point = other->has_current_point;
|
||||
path->has_curve_to = other->has_curve_to;
|
||||
path->last_move_point = other->last_move_point;
|
||||
|
||||
path->buf_head->num_ops = other->buf_head->num_ops;
|
||||
path->buf_head->num_points = other->buf_head->num_points;
|
||||
memcpy (path->buf_head->op, other->buf_head->op,
|
||||
other->buf_head->num_ops * sizeof (other->buf_head->op[0]));
|
||||
memcpy (path->buf_head->points, other->buf_head->points,
|
||||
other->buf_head->num_points * sizeof (other->buf_head->points[0]));
|
||||
for (other_buf = other->buf_head->next;
|
||||
path->buf_head.base.num_ops = other->buf_head.base.num_ops;
|
||||
path->buf_head.base.num_points = other->buf_head.base.num_points;
|
||||
path->buf_head.base.buf_size = other->buf_head.base.buf_size;
|
||||
memcpy (path->buf_head.op, other->buf_head.base.op,
|
||||
other->buf_head.base.num_ops * sizeof (other->buf_head.op[0]));
|
||||
memcpy (path->buf_head.points, other->buf_head.points,
|
||||
other->buf_head.base.num_points * sizeof (other->buf_head.points[0]));
|
||||
for (other_buf = other->buf_head.base.next;
|
||||
other_buf;
|
||||
other_buf = other_buf->next)
|
||||
{
|
||||
buf = _cairo_path_buf_create ();
|
||||
buf = _cairo_path_buf_create (other_buf->buf_size);
|
||||
if (buf == NULL) {
|
||||
_cairo_path_fixed_fini (path);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
memcpy (buf, other_buf, sizeof (cairo_path_buf_t));
|
||||
buf->num_ops = other_buf->num_ops;
|
||||
buf->num_points = other_buf->num_points;
|
||||
memcpy (buf->op, other_buf->op,
|
||||
buf->num_ops * sizeof (buf->op[0]));
|
||||
memcpy (buf->points, other_buf->points,
|
||||
buf->num_points * sizeof (buf->points[0]));
|
||||
_cairo_path_fixed_add_buf (path, buf);
|
||||
}
|
||||
|
||||
@ -120,10 +130,14 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
cairo_path_fixed_t *
|
||||
_cairo_path_fixed_create (void)
|
||||
{
|
||||
cairo_path_fixed_t *path = malloc (sizeof (cairo_path_fixed_t));
|
||||
cairo_path_fixed_t *path;
|
||||
|
||||
if (!path)
|
||||
path = malloc (sizeof (cairo_path_fixed_t));
|
||||
if (!path) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cairo_path_fixed_init (path);
|
||||
return path;
|
||||
}
|
||||
@ -133,17 +147,17 @@ _cairo_path_fixed_fini (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = path->buf_head->next;
|
||||
buf = path->buf_head.base.next;
|
||||
while (buf) {
|
||||
cairo_path_buf_t *this = buf;
|
||||
buf = buf->next;
|
||||
_cairo_path_buf_destroy (this);
|
||||
}
|
||||
path->buf_head->next = NULL;
|
||||
path->buf_head->prev = NULL;
|
||||
path->buf_tail = path->buf_head;
|
||||
path->buf_head->num_ops = 0;
|
||||
path->buf_head->num_points = 0;
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
|
||||
path->has_current_point = FALSE;
|
||||
path->has_curve_to = FALSE;
|
||||
@ -202,7 +216,7 @@ _cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
@ -248,7 +262,7 @@ _cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
@ -298,7 +312,7 @@ _cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x2, y2;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
x0 = path->current_point.x + dx0;
|
||||
y0 = path->current_point.y + dy0;
|
||||
@ -336,18 +350,18 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_get_current_point (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t *x,
|
||||
cairo_fixed_t *y)
|
||||
{
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
return FALSE;
|
||||
|
||||
*x = path->current_point.x;
|
||||
*y = path->current_point.y;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -356,20 +370,20 @@ _cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_point_t *points,
|
||||
int num_points)
|
||||
{
|
||||
if ((unsigned int) path->buf_tail->num_ops + 1 > CAIRO_PATH_BUF_SIZE ||
|
||||
(unsigned int) path->buf_tail->num_points + num_points > CAIRO_PATH_BUF_SIZE)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
cairo_path_buf_t *buf = path->buf_tail;
|
||||
|
||||
buf = _cairo_path_buf_create ();
|
||||
if (buf->num_ops + 1 > buf->buf_size ||
|
||||
buf->num_points + num_points > 2 * buf->buf_size)
|
||||
{
|
||||
buf = _cairo_path_buf_create (buf->buf_size * 2);
|
||||
if (buf == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_path_fixed_add_buf (path, buf);
|
||||
}
|
||||
|
||||
_cairo_path_buf_add_op (path->buf_tail, op);
|
||||
_cairo_path_buf_add_points (path->buf_tail, points, num_points);
|
||||
_cairo_path_buf_add_op (buf, op);
|
||||
_cairo_path_buf_add_points (buf, points, num_points);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -386,17 +400,23 @@ _cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
}
|
||||
|
||||
static cairo_path_buf_t *
|
||||
_cairo_path_buf_create (void)
|
||||
_cairo_path_buf_create (int buf_size)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = malloc (sizeof (cairo_path_buf_t));
|
||||
|
||||
buf = _cairo_malloc_ab_plus_c (buf_size,
|
||||
sizeof (cairo_path_op_t) +
|
||||
2 * sizeof (cairo_point_t),
|
||||
sizeof (cairo_path_buf_t));
|
||||
if (buf) {
|
||||
buf->next = NULL;
|
||||
buf->prev = NULL;
|
||||
buf->num_ops = 0;
|
||||
buf->num_points = 0;
|
||||
buf->buf_size = buf_size;
|
||||
|
||||
buf->op = (cairo_path_op_t *) (buf + 1);
|
||||
buf->points = (cairo_point_t *) (buf->op + buf_size);
|
||||
}
|
||||
|
||||
return buf;
|
||||
@ -450,7 +470,7 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
|
||||
cairo_bool_t forward = (dir == CAIRO_DIRECTION_FORWARD);
|
||||
int step = forward ? 1 : -1;
|
||||
|
||||
for (buf = forward ? path->buf_head : path->buf_tail;
|
||||
for (buf = forward ? &path->buf_head.base : path->buf_tail;
|
||||
buf;
|
||||
buf = forward ? buf->next : buf->prev)
|
||||
{
|
||||
@ -470,7 +490,7 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
|
||||
op = buf->op[i];
|
||||
|
||||
if (! forward) {
|
||||
points -= num_args[op];
|
||||
points -= num_args[(int) op];
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
@ -492,7 +512,7 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
|
||||
return status;
|
||||
|
||||
if (forward) {
|
||||
points += num_args[op];
|
||||
points += num_args[(int) op];
|
||||
}
|
||||
|
||||
}
|
||||
@ -508,7 +528,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley)
|
||||
{
|
||||
cairo_path_buf_t *buf = path->buf_head;
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
int i;
|
||||
|
||||
while (buf) {
|
||||
@ -565,14 +585,19 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
||||
path->last_move_point.y != other->last_move_point.y)
|
||||
return FALSE;
|
||||
|
||||
other_buf = other->buf_head;
|
||||
for (path_buf = path->buf_head; path_buf != NULL; path_buf = path_buf->next) {
|
||||
other_buf = &other->buf_head.base;
|
||||
for (path_buf = &path->buf_head.base;
|
||||
path_buf != NULL;
|
||||
path_buf = path_buf->next)
|
||||
{
|
||||
if (other_buf == NULL ||
|
||||
path_buf->num_ops != other_buf->num_ops ||
|
||||
path_buf->num_points != other_buf->num_points ||
|
||||
memcmp (path_buf->op, other_buf->op, path_buf->num_ops) != 0 ||
|
||||
memcmp (path_buf->points, other_buf->points, path_buf->num_points != 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
other_buf = other_buf->next;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@ -39,8 +39,6 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
extern const cairo_private cairo_path_t _cairo_path_nil;
|
||||
|
||||
cairo_private cairo_path_t *
|
||||
_cairo_path_create (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate);
|
||||
|
||||
@ -272,19 +272,51 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
||||
double in_dot_out = ((-in->usr_vector.x * out->usr_vector.x)+
|
||||
(-in->usr_vector.y * out->usr_vector.y));
|
||||
double ml = stroker->style->miter_limit;
|
||||
double tolerance_squared = stroker->tolerance * stroker->tolerance;
|
||||
double line_width_squared = (stroker->style->line_width *
|
||||
stroker->style->line_width);
|
||||
|
||||
/*
|
||||
* Check the miter limit -- lines meeting at an acute angle
|
||||
/* Check the miter limit -- lines meeting at an acute angle
|
||||
* can generate long miters, the limit converts them to bevel
|
||||
*
|
||||
* We want to know when the miter is within the miter limit.
|
||||
* That's straightforward to specify:
|
||||
* Consider the miter join formed when two line segments
|
||||
* meet at an angle psi:
|
||||
*
|
||||
* secant (psi / 2) <= ml
|
||||
* /.\
|
||||
* /. .\
|
||||
* /./ \.\
|
||||
* /./psi\.\
|
||||
*
|
||||
* where psi is the angle between in and out
|
||||
* We can zoom in on the right half of that to see:
|
||||
*
|
||||
* |\
|
||||
* | \ psi/2
|
||||
* | \
|
||||
* | \
|
||||
* | \
|
||||
* | \
|
||||
* miter \
|
||||
* length \
|
||||
* | \
|
||||
* | .\
|
||||
* | . \
|
||||
* |. line \
|
||||
* \ width \
|
||||
* \ \
|
||||
*
|
||||
*
|
||||
* The right triangle in that figure, (the line-width side is
|
||||
* shown faintly with three '.' characters), gives us the
|
||||
* following expression relating miter length, angle and line
|
||||
* width:
|
||||
*
|
||||
* 1 /sin (psi/2) = miter_length / line_width
|
||||
*
|
||||
* The right-hand side of this relationship is the same ratio
|
||||
* in which the miter limit (ml) is expressed. We want to know
|
||||
* when the miter length is within the miter limit. That is
|
||||
* when the following condition holds:
|
||||
*
|
||||
* secant(psi/2) = 1/sin(psi/2)
|
||||
* 1/sin(psi/2) <= ml
|
||||
* 1 <= ml sin(psi/2)
|
||||
* 1 <= ml² sin²(psi/2)
|
||||
@ -300,8 +332,79 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
||||
*
|
||||
* 2 <= ml² (1 - in · out)
|
||||
*
|
||||
*
|
||||
* That gives us the condition to avoid generating miters that
|
||||
* are too large from angles that are too large. But we also
|
||||
* need to avoid generating miters when the angle is very small.
|
||||
*
|
||||
* The miter formed from a tiny angle is also tiny, so the
|
||||
* miter limit is not a concern. But with a tiny angle we will
|
||||
* be computing the intersection of two lines that are very
|
||||
* near parallel. Also, the limits of the fixed-point grid on
|
||||
* the input face coordinates mean that the resulting
|
||||
* intersection could be wildly wrong. (See the
|
||||
* get-path-extents test case for a call to cairo_arc that
|
||||
* results in two problematic faces.)
|
||||
*
|
||||
* Fortunately we can also derive an expression for when using
|
||||
* a bevel join instead of a miter will introduce an error no
|
||||
* larger than the tolerance. Consider the same join from
|
||||
* before but with the miter now chopped off and replaced with
|
||||
* a bevel join. The drawing is zoomed in a bit again, the
|
||||
* point marked as '*' is the center of the stroke---the point
|
||||
* where the two line segments of interest intersect:
|
||||
*
|
||||
* ----- .
|
||||
* ^ ..
|
||||
* | . .
|
||||
* | . .
|
||||
* 1/2 . .
|
||||
* miter . . |
|
||||
* length . . |
|
||||
* | .______. ___v___
|
||||
* | | . \ 1/2 bevel
|
||||
* v | . \ width
|
||||
* ---- * \ -------
|
||||
* | \ ^
|
||||
*
|
||||
*
|
||||
* The length of interest here is the vertical length of the
|
||||
* miter that is eliminated. It's length can be obtained by
|
||||
* starting with 1/2 the miter length and the subtracting off
|
||||
* the vertical length that is included by the bevel join,
|
||||
* (here termed 1/2 bevel width). To determine this new bevel
|
||||
* width, we have a small right triangle shown, the hypotenuse
|
||||
* of which has a length of 1/2 the line width, and the small
|
||||
* angle at the upper right of the figure is psi/2.
|
||||
*
|
||||
* So we have:
|
||||
*
|
||||
* sin (psi/2) = (bevel_width / 2) / (line_width / 2)
|
||||
*
|
||||
* And we can determine when the miter is required by
|
||||
* calculating when the eliminated portion of the miter is
|
||||
* greater than the tolerance:
|
||||
*
|
||||
* (miter_length / 2) - (bevel_width / 2) > tolerance
|
||||
*
|
||||
* Substituting in the above expressions for miter_length and
|
||||
* bevel_width:
|
||||
*
|
||||
* (line_width/2) / sin (psi/2) - (line_width/2) * sin (psi/2) > tolerance
|
||||
* 1 / sin(psi/2) - sin (psi/2) > 2 * tolerance / line_width
|
||||
* 1 / sin²(psi/2) -2 + sin²(psi/2) > 4 * (tolerance/line_width)²
|
||||
*
|
||||
* Use identity: sin²(psi/2) = (1-cos(psi))/2
|
||||
|
||||
* 2/(1 - cos(psi)) - 2 + (1-cos(psi))/2 > 4 * (tolerance/line_width)²
|
||||
* 4/(1 - cos(psi)) - 4 + (1-cos(psi)) > 8 * (tolerance/line_width)²
|
||||
* 4/(1 - cos(psi)) + (1-cos(psi)) > 8 * ((tolerance/line_width)² + 0.5)
|
||||
*/
|
||||
if (2 <= ml * ml * (1 - in_dot_out)) {
|
||||
if ((2 <= ml * ml * (1 - in_dot_out)) &&
|
||||
((8 * (tolerance_squared / line_width_squared + 0.5)) <
|
||||
4 / (1 - in_dot_out) + (1 - in_dot_out))
|
||||
)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
double mx, my;
|
||||
double dx1, dx2, dy1, dy2;
|
||||
@ -816,7 +919,7 @@ _cairo_stroker_curve_to (void *closure,
|
||||
if (stroker->has_current_face) {
|
||||
status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
|
||||
if (status)
|
||||
return status;
|
||||
goto CLEANUP_PEN;
|
||||
} else if (!stroker->has_first_face) {
|
||||
stroker->first_face = start;
|
||||
stroker->has_first_face = TRUE;
|
||||
@ -1064,9 +1167,11 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
|
||||
/* Common case is one rectangle of exactly 4 segments. */
|
||||
if (new_size == 0)
|
||||
new_size = 4;
|
||||
new_segments = realloc (stroker->segments, new_size * sizeof (cairo_line_t));
|
||||
new_segments = _cairo_realloc_ab (stroker->segments,
|
||||
new_size, sizeof (cairo_line_t));
|
||||
if (new_segments == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
stroker->segments_size = new_size;
|
||||
stroker->segments = new_segments;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
#include "cairo-path-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
|
||||
static const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
|
||||
|
||||
/* Closure for path interpretation. */
|
||||
typedef struct cairo_path_count {
|
||||
@ -339,7 +339,7 @@ _cairo_path_populate (cairo_path_t *path,
|
||||
/* Sanity check the count */
|
||||
assert (cpp.data - path->data == path->num_data);
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_path_t *
|
||||
@ -352,8 +352,10 @@ _cairo_path_create_in_error (cairo_status_t status)
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
|
||||
path = malloc (sizeof (cairo_path_t));
|
||||
if (path == NULL)
|
||||
if (path == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->num_data = 0;
|
||||
path->data = NULL;
|
||||
@ -370,25 +372,34 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
|
||||
cairo_path_t *path;
|
||||
|
||||
path = malloc (sizeof (cairo_path_t));
|
||||
if (path == NULL)
|
||||
if (path == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->num_data = _cairo_path_count (path, path_fixed,
|
||||
_cairo_gstate_get_tolerance (gstate),
|
||||
flatten);
|
||||
if (path->num_data <= 0) {
|
||||
if (path->num_data < 0) {
|
||||
free (path);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->data = _cairo_malloc_ab (path->num_data, sizeof (cairo_path_data_t));
|
||||
if (path->data == NULL) {
|
||||
free (path);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
if (path->num_data) {
|
||||
path->data = _cairo_malloc_ab (path->num_data,
|
||||
sizeof (cairo_path_data_t));
|
||||
if (path->data == NULL) {
|
||||
free (path);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_path_t*) &_cairo_path_nil;
|
||||
}
|
||||
|
||||
path->status = _cairo_path_populate (path, path_fixed,
|
||||
gstate, flatten);
|
||||
path->status = _cairo_path_populate (path, path_fixed,
|
||||
gstate, flatten);
|
||||
} else {
|
||||
path->data = NULL;
|
||||
path->status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
@ -413,8 +424,9 @@ cairo_path_destroy (cairo_path_t *path)
|
||||
if (path == NULL || path == &_cairo_path_nil)
|
||||
return;
|
||||
|
||||
free (path->data);
|
||||
path->num_data = 0;
|
||||
if (path->data)
|
||||
free (path->data);
|
||||
|
||||
free (path);
|
||||
}
|
||||
|
||||
@ -484,19 +496,19 @@ _cairo_path_append_to_context (const cairo_path_t *path,
|
||||
switch (p->header.type) {
|
||||
case CAIRO_PATH_MOVE_TO:
|
||||
if (p->header.length < 2)
|
||||
return CAIRO_STATUS_INVALID_PATH_DATA;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_move_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_LINE_TO:
|
||||
if (p->header.length < 2)
|
||||
return CAIRO_STATUS_INVALID_PATH_DATA;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_line_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_CURVE_TO:
|
||||
if (p->header.length < 4)
|
||||
return CAIRO_STATUS_INVALID_PATH_DATA;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_curve_to (cr,
|
||||
p[1].point.x, p[1].point.y,
|
||||
p[2].point.x, p[2].point.y,
|
||||
@ -504,11 +516,11 @@ _cairo_path_append_to_context (const cairo_path_t *path,
|
||||
break;
|
||||
case CAIRO_PATH_CLOSE_PATH:
|
||||
if (p->header.length < 1)
|
||||
return CAIRO_STATUS_INVALID_PATH_DATA;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_close_path (cr);
|
||||
break;
|
||||
default:
|
||||
return CAIRO_STATUS_INVALID_PATH_DATA;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
}
|
||||
|
||||
status = cairo_status (cr);
|
||||
|
||||
@ -32,31 +32,31 @@
|
||||
|
||||
const cairo_solid_pattern_t _cairo_pattern_nil = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NULL_POINTER,/* status */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NULL_POINTER, /* status */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
const cairo_solid_pattern_t cairo_pattern_none = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_SUCCESS, /* status */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
|
||||
CAIRO_FILTER_DEFAULT, /* filter */
|
||||
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
|
||||
};
|
||||
|
||||
@ -66,27 +66,26 @@ const cairo_solid_pattern_t cairo_pattern_none = {
|
||||
* @status: a status value indicating an error, (eg. not
|
||||
* CAIRO_STATUS_SUCCESS)
|
||||
*
|
||||
* Sets pattern->status to @status and calls _cairo_error;
|
||||
* Atomically sets pattern->status to @status and calls _cairo_error;
|
||||
*
|
||||
* All assignments of an error status to pattern->status should happen
|
||||
* through _cairo_pattern_set_error() or else _cairo_error() should be
|
||||
* called immediately after the assignment.
|
||||
* through _cairo_pattern_set_error(). Note that due to the nature of
|
||||
* the atomic operation, it is not safe to call this function on the nil
|
||||
* objects.
|
||||
*
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
**/
|
||||
static void
|
||||
static cairo_status_t
|
||||
_cairo_pattern_set_error (cairo_pattern_t *pattern,
|
||||
cairo_status_t status)
|
||||
{
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. It also avoids attempting
|
||||
* to write to read-only data (eg. from a nil pattern). */
|
||||
if (pattern->status == CAIRO_STATUS_SUCCESS)
|
||||
pattern->status = status;
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&pattern->status, status);
|
||||
|
||||
_cairo_error (status);
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -95,7 +94,7 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
pattern->type = type;
|
||||
pattern->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
|
||||
pattern->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_user_data_array_init (&pattern->user_data);
|
||||
@ -138,8 +137,7 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
|
||||
if (pattern->stops == NULL) {
|
||||
pattern->stops_size = 0;
|
||||
pattern->n_stops = 0;
|
||||
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
memcpy (pattern->stops, other->stops,
|
||||
@ -153,10 +151,8 @@ cairo_status_t
|
||||
_cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other)
|
||||
{
|
||||
if (other->status) {
|
||||
_cairo_pattern_set_error (pattern, other->status);
|
||||
return other->status;
|
||||
}
|
||||
if (other->status)
|
||||
return _cairo_pattern_set_error (pattern, other->status);
|
||||
|
||||
switch (other->type) {
|
||||
case CAIRO_PATTERN_TYPE_SOLID: {
|
||||
@ -186,7 +182,7 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
}
|
||||
|
||||
/* The reference count and user_data array are unique to the copy. */
|
||||
pattern->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
|
||||
_cairo_user_data_array_init (&pattern->user_data);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -345,8 +341,8 @@ _cairo_pattern_create_in_error (cairo_status_t status)
|
||||
|
||||
pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK),
|
||||
CAIRO_CONTENT_COLOR);
|
||||
/* no-op on a pattern already in error i.e the _cairo_pattern_nil */
|
||||
_cairo_pattern_set_error (pattern, status);
|
||||
if (pattern->status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_pattern_set_error (pattern, status);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
@ -386,7 +382,7 @@ cairo_pattern_create_rgb (double red, double green, double blue)
|
||||
pattern = _cairo_pattern_create_solid (&color,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
if (pattern->status)
|
||||
_cairo_error (pattern->status);
|
||||
_cairo_error_throw (pattern->status);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
@ -430,7 +426,7 @@ cairo_pattern_create_rgba (double red, double green, double blue,
|
||||
pattern = _cairo_pattern_create_solid (&color,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
if (pattern->status)
|
||||
_cairo_error (pattern->status);
|
||||
_cairo_error_throw (pattern->status);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
@ -464,7 +460,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
|
||||
|
||||
pattern = malloc (sizeof (cairo_surface_pattern_t));
|
||||
if (pattern == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *)&_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
@ -507,7 +503,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
|
||||
|
||||
pattern = malloc (sizeof (cairo_linear_pattern_t));
|
||||
if (pattern == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
@ -552,7 +548,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
|
||||
|
||||
pattern = malloc (sizeof (cairo_radial_pattern_t));
|
||||
if (pattern == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
@ -577,12 +573,13 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
|
||||
cairo_pattern_t *
|
||||
cairo_pattern_reference (cairo_pattern_t *pattern)
|
||||
{
|
||||
if (pattern == NULL || pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (pattern == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
|
||||
return pattern;
|
||||
|
||||
assert (pattern->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count));
|
||||
|
||||
pattern->ref_count++;
|
||||
_cairo_reference_count_inc (&pattern->ref_count);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
@ -634,13 +631,13 @@ slim_hidden_def (cairo_pattern_status);
|
||||
void
|
||||
cairo_pattern_destroy (cairo_pattern_t *pattern)
|
||||
{
|
||||
if (pattern == NULL || pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (pattern == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
|
||||
return;
|
||||
|
||||
assert (pattern->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count));
|
||||
|
||||
pattern->ref_count--;
|
||||
if (pattern->ref_count)
|
||||
if (! _cairo_reference_count_dec_and_test (&pattern->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_pattern_fini (pattern);
|
||||
@ -680,10 +677,11 @@ slim_hidden_def (cairo_pattern_destroy);
|
||||
unsigned int
|
||||
cairo_pattern_get_reference_count (cairo_pattern_t *pattern)
|
||||
{
|
||||
if (pattern == NULL || pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (pattern == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
|
||||
return 0;
|
||||
|
||||
return pattern->ref_count;
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&pattern->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,8 +730,8 @@ cairo_pattern_set_user_data (cairo_pattern_t *pattern,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (pattern->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return _cairo_user_data_array_set_data (&pattern->user_data,
|
||||
key, user_data, destroy);
|
||||
@ -763,12 +761,13 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
|
||||
if (new_stops)
|
||||
memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t));
|
||||
} else {
|
||||
new_stops = realloc (pattern->stops, new_size * sizeof (cairo_gradient_stop_t));
|
||||
new_stops = _cairo_realloc_ab (pattern->stops,
|
||||
new_size,
|
||||
sizeof (cairo_gradient_stop_t));
|
||||
}
|
||||
|
||||
if (new_stops == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (new_stops == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pattern->stops = new_stops;
|
||||
pattern->stops_size = new_size;
|
||||
@ -791,7 +790,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
|
||||
if (pattern->n_stops >= pattern->stops_size) {
|
||||
cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
|
||||
if (status) {
|
||||
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_pattern_set_error (&pattern->base, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -980,7 +979,7 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern,
|
||||
inverse = *matrix;
|
||||
status = cairo_matrix_invert (&inverse);
|
||||
if (status)
|
||||
_cairo_pattern_set_error (pattern, status);
|
||||
status = _cairo_pattern_set_error (pattern, status);
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_set_matrix);
|
||||
|
||||
@ -1157,7 +1156,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
|
||||
pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
|
||||
if (pixman_stops == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < pattern->n_stops; i++) {
|
||||
@ -1206,7 +1205,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
free (pixman_stops);
|
||||
|
||||
if (pixman_image == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (_cairo_surface_is_image (dst))
|
||||
{
|
||||
@ -1216,7 +1215,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
if (image->base.status)
|
||||
{
|
||||
pixman_image_unref (pixman_image);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return image->base.status;
|
||||
}
|
||||
|
||||
attr->x_offset = attr->y_offset = 0;
|
||||
@ -1258,7 +1257,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
if (image->base.status) {
|
||||
pixman_image_unref (pixman_image);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return image->base.status;
|
||||
}
|
||||
|
||||
pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR, NULL, 0);
|
||||
@ -1267,7 +1266,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
|
||||
if (!pixman_image_set_transform (pixman_image, &pixman_transform)) {
|
||||
cairo_surface_destroy (&image->base);
|
||||
pixman_image_unref (pixman_image);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
switch (pattern->base.extend) {
|
||||
@ -1328,7 +1327,7 @@ _cairo_pattern_solid_surface_matches (
|
||||
const cairo_solid_pattern_t *pattern,
|
||||
cairo_surface_t *dst)
|
||||
{
|
||||
if (cache->surface->ref_count != 1)
|
||||
if (CAIRO_REFERENCE_COUNT_GET_VALUE (&cache->surface->ref_count) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (! _cairo_color_equal (&cache->color, &pattern->color))
|
||||
@ -1470,7 +1469,7 @@ _gradient_is_opaque (const cairo_gradient_pattern_t *gradient)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < gradient->n_stops; i++)
|
||||
if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (gradient->stops[i].color.alpha))
|
||||
if (! CAIRO_COLOR_IS_OPAQUE (&gradient->stops[i].color))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -2024,7 +2023,7 @@ cairo_pattern_get_rgba (cairo_pattern_t *pattern,
|
||||
double r0, g0, b0, a0;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
_cairo_color_get_rgba (&solid->color, &r0, &g0, &b0, &a0);
|
||||
|
||||
@ -2062,7 +2061,7 @@ cairo_pattern_get_surface (cairo_pattern_t *pattern,
|
||||
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
if (surface)
|
||||
*surface = spat->surface;
|
||||
@ -2101,10 +2100,10 @@ cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
|
||||
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
if (index < 0 || (unsigned int) index >= gradient->n_stops)
|
||||
return CAIRO_STATUS_INVALID_INDEX;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
|
||||
|
||||
if (offset)
|
||||
*offset = _cairo_fixed_to_double(gradient->stops[index].x);
|
||||
@ -2142,7 +2141,7 @@ cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
|
||||
pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
if (count)
|
||||
*count = gradient->n_stops;
|
||||
@ -2174,7 +2173,7 @@ cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
|
||||
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
if (x0)
|
||||
*x0 = _cairo_fixed_to_double (linear->p1.x);
|
||||
@ -2215,7 +2214,7 @@ cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
|
||||
cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
|
||||
if (x0)
|
||||
*x0 = _cairo_fixed_to_double (radial->c1.x);
|
||||
|
||||
@ -83,6 +83,8 @@ struct _cairo_pdf_surface {
|
||||
cairo_pdf_resource_t next_available_resource;
|
||||
cairo_pdf_resource_t pages_resource;
|
||||
|
||||
cairo_bool_t compress_content;
|
||||
|
||||
struct {
|
||||
cairo_bool_t active;
|
||||
cairo_pdf_resource_t self;
|
||||
@ -95,6 +97,7 @@ struct _cairo_pdf_surface {
|
||||
struct {
|
||||
cairo_bool_t active;
|
||||
cairo_output_stream_t *stream;
|
||||
cairo_output_stream_t *mem_stream;
|
||||
cairo_output_stream_t *old_output;
|
||||
cairo_pdf_group_resources_t resources;
|
||||
cairo_bool_t is_knockout;
|
||||
@ -104,6 +107,7 @@ struct _cairo_pdf_surface {
|
||||
struct {
|
||||
cairo_bool_t active;
|
||||
cairo_output_stream_t *stream;
|
||||
cairo_output_stream_t *mem_stream;
|
||||
cairo_output_stream_t *old_output;
|
||||
cairo_pdf_group_resources_t resources;
|
||||
} content_stream;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -78,10 +78,10 @@ _cairo_pen_init (cairo_pen_t *pen,
|
||||
radius,
|
||||
ctm);
|
||||
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/*
|
||||
* Compute pen coordinates. To generate the right ellipse, compute points around
|
||||
@ -119,10 +119,11 @@ _cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
|
||||
*pen = *other;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices,
|
||||
sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (pen->vertices, other->vertices, pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
}
|
||||
|
||||
@ -138,9 +139,10 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
|
||||
int i;
|
||||
|
||||
num_vertices = pen->num_vertices + num_points;
|
||||
vertices = realloc (pen->vertices, num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
vertices = _cairo_realloc_ab (pen->vertices,
|
||||
num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
if (vertices == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pen->vertices = vertices;
|
||||
pen->num_vertices = num_vertices;
|
||||
@ -321,7 +323,13 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
||||
break;
|
||||
}
|
||||
|
||||
assert (i < pen->num_vertices);
|
||||
/* If the desired slope cannot be found between any of the pen
|
||||
* vertices, then we must have a degenerate pen, (such as a pen
|
||||
* that's been transformed to a line). In that case, we consider
|
||||
* the first pen vertex as the appropriate clockwise vertex.
|
||||
*/
|
||||
if (i == pen->num_vertices)
|
||||
i = 0;
|
||||
|
||||
*active = i;
|
||||
}
|
||||
@ -349,6 +357,14 @@ _cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the desired slope cannot be found between any of the pen
|
||||
* vertices, then we must have a degenerate pen, (such as a pen
|
||||
* that's been transformed to a line). In that case, we consider
|
||||
* the last pen vertex as the appropriate counterclockwise vertex.
|
||||
*/
|
||||
if (i < 0)
|
||||
i = pen->num_vertices - 1;
|
||||
|
||||
*active = i;
|
||||
}
|
||||
|
||||
|
||||
@ -88,15 +88,24 @@ convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
|
||||
* return.
|
||||
*/
|
||||
static void
|
||||
png_simple_error_callback (png_structp png_save_ptr,
|
||||
png_simple_error_callback (png_structp png,
|
||||
png_const_charp error_msg)
|
||||
{
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
longjmp (png_save_ptr->jmpbuf, CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
|
||||
/* default to the most likely error */
|
||||
if (*error == CAIRO_STATUS_SUCCESS)
|
||||
*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
longjmp (png_jmpbuf (png), 1);
|
||||
#endif
|
||||
|
||||
/* if we get here, then we have to choice but to abort ... */
|
||||
}
|
||||
|
||||
static void
|
||||
png_simple_warning_callback (png_structp png_save_ptr,
|
||||
png_simple_warning_callback (png_structp png,
|
||||
png_const_charp error_msg)
|
||||
{
|
||||
}
|
||||
@ -108,13 +117,13 @@ write_png (cairo_surface_t *surface,
|
||||
void *closure)
|
||||
{
|
||||
int i;
|
||||
volatile cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_status_t status;
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
png_struct *png;
|
||||
png_info *info;
|
||||
png_time pt;
|
||||
png_byte **rows = NULL;
|
||||
png_byte **volatile rows = NULL;
|
||||
png_color_16 white;
|
||||
int png_color_type;
|
||||
int depth;
|
||||
@ -124,14 +133,14 @@ write_png (cairo_surface_t *surface,
|
||||
&image_extra);
|
||||
|
||||
if (status == CAIRO_STATUS_NO_MEMORY)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
else if (status != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
|
||||
if (image->height && image->width) {
|
||||
rows = _cairo_malloc_ab (image->height, sizeof(png_byte*));
|
||||
rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
|
||||
if (rows == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL1;
|
||||
}
|
||||
|
||||
@ -139,23 +148,24 @@ write_png (cairo_surface_t *surface,
|
||||
rows[i] = (png_byte *) image->data + i * image->stride;
|
||||
}
|
||||
|
||||
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
|
||||
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
|
||||
png_simple_error_callback,
|
||||
png_simple_warning_callback);
|
||||
if (png == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
}
|
||||
|
||||
info = png_create_info_struct (png);
|
||||
if (info == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL3;
|
||||
}
|
||||
|
||||
status = setjmp (png_jmpbuf (png));
|
||||
if (status)
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
if (setjmp (png_jmpbuf (png)))
|
||||
goto BAIL3;
|
||||
#endif
|
||||
|
||||
png_set_write_fn (png, closure, write_func, NULL);
|
||||
|
||||
@ -177,7 +187,7 @@ write_png (cairo_surface_t *surface,
|
||||
png_color_type = PNG_COLOR_TYPE_GRAY;
|
||||
break;
|
||||
default:
|
||||
status = CAIRO_STATUS_INVALID_FORMAT;
|
||||
status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
goto BAIL3;
|
||||
}
|
||||
|
||||
@ -234,8 +244,11 @@ stdio_write_func (png_structp png, png_bytep data, png_size_t size)
|
||||
size_t ret = fwrite (data, 1, size, fp);
|
||||
size -= ret;
|
||||
data += ret;
|
||||
if (size && ferror (fp))
|
||||
png_error(png, "Write Error");
|
||||
if (size && ferror (fp)) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
*error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,12 +276,12 @@ cairo_surface_write_to_png (cairo_surface_t *surface,
|
||||
|
||||
fp = fopen (filename, "wb");
|
||||
if (fp == NULL)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
|
||||
status = write_png (surface, stdio_write_func, fp);
|
||||
|
||||
if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
|
||||
status = CAIRO_STATUS_WRITE_ERROR;
|
||||
status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -286,8 +299,11 @@ stream_write_func (png_structp png, png_bytep data, png_size_t size)
|
||||
|
||||
png_closure = png_get_io_ptr (png);
|
||||
status = png_closure->write_func (png_closure->closure, data, size);
|
||||
if (status)
|
||||
png_error(png, "Write Error");
|
||||
if (status) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
*error = status;
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,10 +385,11 @@ read_png (png_rw_ptr read_func,
|
||||
int depth, color_type, interlace;
|
||||
unsigned int i;
|
||||
unsigned int pixel_size;
|
||||
cairo_status_t status;
|
||||
|
||||
/* XXX: Perhaps we'll want some other error handlers? */
|
||||
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
|
||||
NULL,
|
||||
&status,
|
||||
png_simple_error_callback,
|
||||
png_simple_warning_callback);
|
||||
if (png == NULL)
|
||||
@ -384,10 +401,14 @@ read_png (png_rw_ptr read_func,
|
||||
|
||||
png_set_read_fn (png, closure, read_func);
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
if (setjmp (png_jmpbuf (png))) {
|
||||
surface = (cairo_surface_t*) &_cairo_surface_nil_read_error;
|
||||
if (status != CAIRO_STATUS_NO_MEMORY)
|
||||
surface = (cairo_surface_t*) &_cairo_surface_nil_read_error;
|
||||
goto BAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
png_read_info (png, info);
|
||||
|
||||
@ -408,7 +429,7 @@ read_png (png_rw_ptr read_func,
|
||||
png_set_gray_1_2_4_to_8 (png);
|
||||
#endif
|
||||
/* transform transparency to alpha */
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS))
|
||||
if (png_get_valid (png, info, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha (png);
|
||||
|
||||
if (depth == 16)
|
||||
@ -436,7 +457,7 @@ read_png (png_rw_ptr read_func,
|
||||
if (data == NULL)
|
||||
goto BAIL;
|
||||
|
||||
row_pointers = _cairo_malloc_ab (png_height, sizeof(char *));
|
||||
row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
|
||||
if (row_pointers == NULL)
|
||||
goto BAIL;
|
||||
|
||||
@ -464,7 +485,7 @@ read_png (png_rw_ptr read_func,
|
||||
png_destroy_read_struct (&png, &info, NULL);
|
||||
|
||||
if (surface->status)
|
||||
_cairo_error (surface->status);
|
||||
_cairo_error_throw (surface->status);
|
||||
|
||||
return surface;
|
||||
}
|
||||
@ -479,8 +500,11 @@ stdio_read_func (png_structp png, png_bytep data, png_size_t size)
|
||||
size_t ret = fread (data, 1, size, fp);
|
||||
size -= ret;
|
||||
data += ret;
|
||||
if (size && ferror (fp))
|
||||
png_error(png, "Read Error");
|
||||
if (size && (feof (fp) || ferror (fp))) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
*error = _cairo_error (CAIRO_STATUS_READ_ERROR);
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,13 +534,13 @@ cairo_image_surface_create_from_png (const char *filename)
|
||||
if (fp == NULL) {
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
case ENOENT:
|
||||
_cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
|
||||
_cairo_error_throw (CAIRO_STATUS_FILE_NOT_FOUND);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil_file_not_found;
|
||||
default:
|
||||
_cairo_error (CAIRO_STATUS_READ_ERROR);
|
||||
_cairo_error_throw (CAIRO_STATUS_READ_ERROR);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil_read_error;
|
||||
}
|
||||
}
|
||||
@ -541,8 +565,11 @@ stream_read_func (png_structp png, png_bytep data, png_size_t size)
|
||||
|
||||
png_closure = png_get_io_ptr (png);
|
||||
status = png_closure->read_func (png_closure->closure, data, size);
|
||||
if (status)
|
||||
png_error(png, "Read Error");
|
||||
if (status) {
|
||||
cairo_status_t *error = png_get_error_ptr (png);
|
||||
*error = status;
|
||||
png_error (png, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -97,12 +97,12 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
|
||||
if (new_edges)
|
||||
memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t));
|
||||
} else {
|
||||
new_edges = realloc (polygon->edges, new_size * sizeof (cairo_edge_t));
|
||||
new_edges = _cairo_realloc_ab (polygon->edges,
|
||||
new_size, sizeof (cairo_edge_t));
|
||||
}
|
||||
|
||||
if (new_edges == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (new_edges == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
polygon->edges = new_edges;
|
||||
polygon->edges_size = new_size;
|
||||
|
||||
@ -36,11 +36,12 @@
|
||||
#ifndef CAIRO_PRIVATE_H
|
||||
#define CAIRO_PRIVATE_H
|
||||
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
struct _cairo {
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
|
||||
cairo_status_t status;
|
||||
|
||||
|
||||
@ -57,10 +57,11 @@ typedef struct cairo_ps_surface {
|
||||
FILE *tmpfile;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
cairo_bool_t eps;
|
||||
cairo_content_t content;
|
||||
double width;
|
||||
double height;
|
||||
double max_width;
|
||||
double max_height;
|
||||
int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
|
||||
|
||||
int num_pages;
|
||||
|
||||
@ -76,6 +77,8 @@ typedef struct cairo_ps_surface {
|
||||
|
||||
cairo_array_t *dsc_comment_target;
|
||||
|
||||
cairo_ps_level_t ps_level;
|
||||
|
||||
cairo_surface_t *paginated_surface;
|
||||
} cairo_ps_surface_t;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -47,6 +47,20 @@ CAIRO_BEGIN_DECLS
|
||||
|
||||
/* PS-surface functions */
|
||||
|
||||
/**
|
||||
* cairo_ps_level_t
|
||||
* @CAIRO_PS_LEVEL_2: The language level 2 of the PostScript specification.
|
||||
* @CAIRO_PS_LEVEL_3: The language level 3 of the PostScript specification.
|
||||
*
|
||||
* #cairo_ps_level_t is used to describe the language level of the
|
||||
* PostScript Language Reference that a generated PostScript file will
|
||||
* conform to.
|
||||
*/
|
||||
typedef enum _cairo_ps_level {
|
||||
CAIRO_PS_LEVEL_2,
|
||||
CAIRO_PS_LEVEL_3
|
||||
} cairo_ps_level_t;
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_ps_surface_create (const char *filename,
|
||||
double width_in_points,
|
||||
@ -58,6 +72,24 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_restrict_to_level (cairo_surface_t *surface,
|
||||
cairo_ps_level_t level);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_get_levels (cairo_ps_level_t const **levels,
|
||||
int *num_levels);
|
||||
|
||||
cairo_public const char *
|
||||
cairo_ps_level_to_string (cairo_ps_level_t level);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_eps (cairo_surface_t *surface,
|
||||
cairo_bool_t eps);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_ps_surface_get_eps (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
|
||||
@ -72,9 +72,6 @@ _cairo_atsui_scaled_font_get_atsu_style (cairo_scaled_font_t *sfont);
|
||||
|
||||
ATSUFontID
|
||||
_cairo_atsui_scaled_font_get_atsu_font_id (cairo_scaled_font_t *sfont);
|
||||
|
||||
CGFontRef
|
||||
_cairo_atsui_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
|
||||
#endif /* CAIRO_HAS_ATSUI_FONT */
|
||||
|
||||
#endif /* CAIRO_QUARTZ_PRIVATE_H */
|
||||
|
||||
@ -38,6 +38,14 @@
|
||||
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
/* The 10.5 SDK includes a funky new definition of FloatToFixed which
|
||||
* causes all sorts of breakage; so reset to old-style definition
|
||||
*/
|
||||
#ifdef FloatToFixed
|
||||
#undef FloatToFixed
|
||||
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
|
||||
#endif
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <limits.h>
|
||||
|
||||
@ -90,6 +98,8 @@ CG_EXTERN void CGContextReplacePathWithStrokedPath (CGContextRef);
|
||||
CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
|
||||
#endif
|
||||
|
||||
/* missing in 10.3.9 */
|
||||
extern void CGContextClipToMask (CGContextRef, CGRect, CGImageRef) __attribute__((weak_import));
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
@ -315,10 +325,10 @@ ComputeGradientValue (void *info, const float *in, float *out)
|
||||
if (i == 0 || i == grad->n_stops) {
|
||||
if (i == grad->n_stops)
|
||||
--i;
|
||||
out[0] = grad->stops[i].color.red / 65535.;
|
||||
out[1] = grad->stops[i].color.green / 65535.;
|
||||
out[2] = grad->stops[i].color.blue / 65535.;
|
||||
out[3] = grad->stops[i].color.alpha / 65535.;
|
||||
out[0] = grad->stops[i].color.red;
|
||||
out[1] = grad->stops[i].color.green;
|
||||
out[2] = grad->stops[i].color.blue;
|
||||
out[3] = grad->stops[i].color.alpha;
|
||||
} else {
|
||||
float ax = _cairo_fixed_to_double(grad->stops[i-1].x);
|
||||
float bx = _cairo_fixed_to_double(grad->stops[i].x) - ax;
|
||||
@ -326,17 +336,17 @@ ComputeGradientValue (void *info, const float *in, float *out)
|
||||
float ap = 1.0 - bp;
|
||||
|
||||
out[0] =
|
||||
(grad->stops[i-1].color.red / 65535.) * ap +
|
||||
(grad->stops[i].color.red / 65535.) * bp;
|
||||
grad->stops[i-1].color.red * ap +
|
||||
grad->stops[i].color.red * bp;
|
||||
out[1] =
|
||||
(grad->stops[i-1].color.green / 65535.) * ap +
|
||||
(grad->stops[i].color.green / 65535.) * bp;
|
||||
grad->stops[i-1].color.green * ap +
|
||||
grad->stops[i].color.green * bp;
|
||||
out[2] =
|
||||
(grad->stops[i-1].color.blue / 65535.) * ap +
|
||||
(grad->stops[i].color.blue / 65535.) * bp;
|
||||
grad->stops[i-1].color.blue * ap +
|
||||
grad->stops[i].color.blue * bp;
|
||||
out[3] =
|
||||
(grad->stops[i-1].color.alpha / 65535.) * ap +
|
||||
(grad->stops[i].color.alpha / 65535.) * bp;
|
||||
grad->stops[i-1].color.alpha * ap +
|
||||
grad->stops[i].color.alpha * bp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,22 +367,23 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat)
|
||||
&callbacks);
|
||||
}
|
||||
|
||||
static CGShadingRef
|
||||
_cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat,
|
||||
CGShadingRef *shading)
|
||||
{
|
||||
cairo_matrix_t mat;
|
||||
double x0, y0;
|
||||
|
||||
if (abspat->type != CAIRO_PATTERN_TYPE_LINEAR &&
|
||||
abspat->type != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return NULL;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* bandaid for mozilla bug 379321, also visible in the
|
||||
* linear-gradient-reflect test.
|
||||
*/
|
||||
if (abspat->extend == CAIRO_EXTEND_REFLECT ||
|
||||
abspat->extend == CAIRO_EXTEND_REPEAT)
|
||||
return NULL;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* We can only do this if we have an identity pattern matrix;
|
||||
* otherwise fall back through to the generic pattern case.
|
||||
@ -383,17 +394,17 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
||||
*/
|
||||
cairo_pattern_get_matrix (abspat, &mat);
|
||||
if (mat.xx != 1.0 || mat.yy != 1.0 || mat.xy != 0.0 || mat.yx != 0.0)
|
||||
return NULL;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
x0 = mat.x0;
|
||||
y0 = mat.y0;
|
||||
|
||||
if (abspat->type == CAIRO_PATTERN_TYPE_LINEAR) {
|
||||
cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t*) abspat;
|
||||
CGShadingRef shading;
|
||||
CGPoint start, end;
|
||||
CGFunctionRef gradFunc;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
bool extend = abspat->extend == CAIRO_EXTEND_PAD;
|
||||
|
||||
start = CGPointMake (_cairo_fixed_to_double (lpat->p1.x) - x0,
|
||||
_cairo_fixed_to_double (lpat->p1.y) - y0);
|
||||
@ -402,22 +413,22 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
||||
|
||||
cairo_pattern_reference (abspat);
|
||||
gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat);
|
||||
shading = CGShadingCreateAxial (rgb,
|
||||
*shading = CGShadingCreateAxial (rgb,
|
||||
start, end,
|
||||
gradFunc,
|
||||
true, true);
|
||||
extend, extend);
|
||||
CGColorSpaceRelease(rgb);
|
||||
CGFunctionRelease(gradFunc);
|
||||
|
||||
return shading;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (abspat->type == CAIRO_PATTERN_TYPE_RADIAL) {
|
||||
cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t*) abspat;
|
||||
CGShadingRef shading;
|
||||
CGPoint start, end;
|
||||
CGFunctionRef gradFunc;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
bool extend = abspat->extend == CAIRO_EXTEND_PAD;
|
||||
|
||||
start = CGPointMake (_cairo_fixed_to_double (rpat->c1.x) - x0,
|
||||
_cairo_fixed_to_double (rpat->c1.y) - y0);
|
||||
@ -426,29 +437,30 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
||||
|
||||
cairo_pattern_reference (abspat);
|
||||
gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat);
|
||||
shading = CGShadingCreateRadial (rgb,
|
||||
*shading = CGShadingCreateRadial (rgb,
|
||||
start,
|
||||
_cairo_fixed_to_double (rpat->r1),
|
||||
end,
|
||||
_cairo_fixed_to_double (rpat->r2),
|
||||
gradFunc,
|
||||
true, true);
|
||||
extend, extend);
|
||||
CGColorSpaceRelease(rgb);
|
||||
CGFunctionRelease(gradFunc);
|
||||
|
||||
return shading;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Shouldn't be reached */
|
||||
ASSERT_NOT_REACHED;
|
||||
return NULL;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* generic cairo surface -> cairo_quartz_surface_t function */
|
||||
static cairo_quartz_surface_t *
|
||||
_cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_surf)
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_to_quartz (cairo_surface_t *target,
|
||||
cairo_surface_t *pat_surf,
|
||||
cairo_quartz_surface_t **quartz_surf)
|
||||
{
|
||||
cairo_quartz_surface_t *quartz_surf = NULL;
|
||||
|
||||
if (cairo_surface_get_type(pat_surf) != CAIRO_SURFACE_TYPE_QUARTZ) {
|
||||
/* XXXtodo/perf don't use clone if the source surface is an image surface! Instead,
|
||||
@ -458,35 +470,41 @@ _cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_s
|
||||
cairo_surface_t *ref_type = target;
|
||||
cairo_surface_t *new_surf = NULL;
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_status_t status;
|
||||
|
||||
if (ref_type == NULL)
|
||||
ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
|
||||
_cairo_surface_get_extents (pat_surf, &rect);
|
||||
status = _cairo_surface_get_extents (pat_surf, &rect);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y,
|
||||
status = _cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y,
|
||||
rect.width, rect.height, &new_surf);
|
||||
|
||||
if (target == NULL)
|
||||
cairo_surface_destroy(ref_type);
|
||||
|
||||
quartz_surf = (cairo_quartz_surface_t *) new_surf;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (new_surf &&
|
||||
cairo_surface_get_type (new_surf) != CAIRO_SURFACE_TYPE_QUARTZ) {
|
||||
if (new_surf &&
|
||||
cairo_surface_get_type (new_surf) != CAIRO_SURFACE_TYPE_QUARTZ)
|
||||
{
|
||||
ND((stderr, "got a non-quartz surface, format=%d width=%u height=%u type=%d\n", cairo_surface_get_type (pat_surf), rect.width, rect.height, cairo_surface_get_type (new_surf)));
|
||||
cairo_surface_destroy (new_surf);
|
||||
quartz_surf = NULL;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*quartz_surf = (cairo_quartz_surface_t *) new_surf;
|
||||
} else {
|
||||
/* If it's a quartz surface, we can try to see if it's a CGBitmapContext;
|
||||
* we do this when we call CGBitmapContextCreateImage below.
|
||||
*/
|
||||
cairo_surface_reference (pat_surf);
|
||||
quartz_surf = (cairo_quartz_surface_t*) pat_surf;
|
||||
|
||||
*quartz_surf = (cairo_quartz_surface_t*) pat_surf;
|
||||
}
|
||||
|
||||
return quartz_surf;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Generic cairo_pattern -> CGPattern function */
|
||||
@ -495,17 +513,21 @@ SurfacePatternDrawFunc (void *info, CGContextRef context)
|
||||
{
|
||||
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info;
|
||||
cairo_surface_t *pat_surf = spat->surface;
|
||||
cairo_int_status_t status;
|
||||
|
||||
cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (NULL, pat_surf);
|
||||
if (!quartz_surf)
|
||||
return;
|
||||
|
||||
CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
|
||||
cairo_quartz_surface_t *quartz_surf;
|
||||
CGImageRef img;
|
||||
CGRect imageBounds;
|
||||
|
||||
status = _cairo_quartz_surface_to_quartz (NULL, pat_surf, &quartz_surf);
|
||||
if (status)
|
||||
return;
|
||||
|
||||
img = CGBitmapContextCreateImage (quartz_surf->cgContext);
|
||||
if (!img) {
|
||||
// ... give up.
|
||||
ND((stderr, "CGBitmapContextCreateImage failed\n"));
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_surface_destroy ((cairo_surface_t*)quartz_surf);
|
||||
return;
|
||||
}
|
||||
@ -570,9 +592,10 @@ _init_pattern_with_snapshot (cairo_pattern_t *pattern,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static CGPatternRef
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t *dest,
|
||||
cairo_pattern_t *abspat)
|
||||
cairo_pattern_t *abspat,
|
||||
CGPatternRef *cgpat)
|
||||
{
|
||||
cairo_surface_pattern_t *spat;
|
||||
cairo_surface_t *pat_surf;
|
||||
@ -583,8 +606,8 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
||||
CGPatternCallbacks cb = { 0,
|
||||
SurfacePatternDrawFunc,
|
||||
(CGFunctionReleaseInfoCallback) cairo_pattern_destroy };
|
||||
CGPatternRef cgpat;
|
||||
float rw, rh;
|
||||
cairo_status_t status;
|
||||
|
||||
cairo_pattern_union_t *snap_pattern = NULL;
|
||||
cairo_pattern_t *target_pattern = abspat;
|
||||
@ -592,12 +615,15 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
||||
cairo_matrix_t m;
|
||||
/* SURFACE is the only type we'll handle here */
|
||||
if (abspat->type != CAIRO_PATTERN_TYPE_SURFACE)
|
||||
return NULL;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
spat = (cairo_surface_pattern_t *) abspat;
|
||||
pat_surf = spat->surface;
|
||||
|
||||
_cairo_surface_get_extents (pat_surf, &extents);
|
||||
status = _cairo_surface_get_extents (pat_surf, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
pbounds.origin.x = 0;
|
||||
pbounds.origin.y = 0;
|
||||
|
||||
@ -649,14 +675,14 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
||||
target_pattern = abspat;
|
||||
}
|
||||
|
||||
cgpat = CGPatternCreate (target_pattern,
|
||||
*cgpat = CGPatternCreate (target_pattern,
|
||||
pbounds,
|
||||
ptransform,
|
||||
rw, rh,
|
||||
kCGPatternTilingConstantSpacing, /* kCGPatternTilingNoDistortion, */
|
||||
TRUE,
|
||||
&cb);
|
||||
return cgpat;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@ -691,8 +717,11 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||
} else if (source->type == CAIRO_PATTERN_TYPE_LINEAR ||
|
||||
source->type == CAIRO_PATTERN_TYPE_RADIAL)
|
||||
{
|
||||
CGShadingRef shading = _cairo_quartz_cairo_gradient_pattern_to_quartz (source);
|
||||
if (!shading)
|
||||
CGShadingRef shading = NULL;
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_quartz_cairo_gradient_pattern_to_quartz (source, &shading);
|
||||
if (status)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
surface->sourceShading = shading;
|
||||
@ -703,14 +732,17 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||
{
|
||||
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
|
||||
cairo_surface_t *pat_surf = spat->surface;
|
||||
cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf);
|
||||
if (!quartz_surf)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
|
||||
cairo_quartz_surface_t *quartz_surf;
|
||||
CGImageRef img;
|
||||
cairo_matrix_t m = spat->base.matrix;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf, &quartz_surf);
|
||||
if (status)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
img = CGBitmapContextCreateImage (quartz_surf->cgContext);
|
||||
if (!img)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
@ -719,7 +751,10 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||
cairo_matrix_invert(&m);
|
||||
_cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceImageTransform);
|
||||
|
||||
_cairo_surface_get_extents (pat_surf, &extents);
|
||||
status = _cairo_surface_get_extents (pat_surf, &extents);
|
||||
if (status)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height);
|
||||
|
||||
surface->sourceImageSurface = (cairo_surface_t *)quartz_surf;
|
||||
@ -728,9 +763,11 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||
} else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
float patternAlpha = 1.0f;
|
||||
CGColorSpaceRef patternSpace;
|
||||
CGPatternRef pattern;
|
||||
cairo_int_status_t status;
|
||||
|
||||
CGPatternRef pattern = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source);
|
||||
if (!pattern)
|
||||
status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, &pattern);
|
||||
if (status)
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
// Save before we change the pattern, colorspace, etc. so that
|
||||
@ -910,13 +947,18 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||
|
||||
//ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface));
|
||||
|
||||
*image_extra = NULL;
|
||||
|
||||
return _cairo_quartz_get_image (surface, image_out, NULL);
|
||||
status = _cairo_quartz_get_image (surface, image_out, NULL);
|
||||
if (status)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -945,7 +987,7 @@ _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
|
||||
|
||||
status = _cairo_quartz_get_image (surface, image_out, &data);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
*image_extra = data;
|
||||
|
||||
@ -966,6 +1008,7 @@ _cairo_quartz_surface_release_dest_image (void *abstract_surface,
|
||||
|
||||
if (!CGBitmapContextGetData (surface->cgContext)) {
|
||||
CGDataProviderRef dataProvider;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef img;
|
||||
|
||||
dataProvider = CGDataProviderCreateWithData (NULL, imageData,
|
||||
@ -975,12 +1018,13 @@ _cairo_quartz_surface_release_dest_image (void *abstract_surface,
|
||||
img = CGImageCreate (surface->extents.width, surface->extents.height,
|
||||
8, 32,
|
||||
surface->extents.width * 4,
|
||||
CGColorSpaceCreateDeviceRGB(),
|
||||
rgb,
|
||||
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
|
||||
dataProvider,
|
||||
NULL,
|
||||
false,
|
||||
kCGRenderingIntentDefault);
|
||||
CGColorSpaceRelease (rgb);
|
||||
|
||||
CGContextSetCompositeOperation (surface->cgContext, kPrivateCGCompositeCopy);
|
||||
|
||||
@ -1079,7 +1123,6 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface,
|
||||
|
||||
new_format = isurf->format;
|
||||
|
||||
|
||||
dataProvider = CGDataProviderCreateWithData (NULL,
|
||||
isurf->data,
|
||||
isurf->height * isurf->stride,
|
||||
@ -1221,7 +1264,9 @@ _cairo_quartz_surface_fill (void *abstract_surface,
|
||||
|
||||
stroke.cgContext = surface->cgContext;
|
||||
stroke.ctm_inverse = NULL;
|
||||
_cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
rv = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
if (rv)
|
||||
goto BAIL;
|
||||
|
||||
if (action == DO_SOLID || action == DO_PATTERN) {
|
||||
if (fill_rule == CAIRO_FILL_RULE_WINDING)
|
||||
@ -1257,6 +1302,7 @@ _cairo_quartz_surface_fill (void *abstract_surface,
|
||||
rv = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
BAIL:
|
||||
_cairo_quartz_teardown_source (surface, source);
|
||||
|
||||
CGContextRestoreGState (surface->cgContext);
|
||||
@ -1303,15 +1349,20 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
||||
#define STATIC_DASH 32
|
||||
float sdash[STATIC_DASH];
|
||||
float *fdash = sdash;
|
||||
unsigned int max_dashes = style->num_dashes;
|
||||
unsigned int k;
|
||||
if (style->num_dashes > STATIC_DASH)
|
||||
fdash = _cairo_malloc_ab (style->num_dashes, sizeof (float));
|
||||
|
||||
for (k = 0; k < style->num_dashes; k++)
|
||||
fdash[k] = (float) style->dash[k];
|
||||
if (style->num_dashes%2)
|
||||
max_dashes *= 2;
|
||||
if (max_dashes > STATIC_DASH)
|
||||
fdash = _cairo_malloc_ab (max_dashes, sizeof (float));
|
||||
if (fdash == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, style->num_dashes);
|
||||
for (k = 0; k < max_dashes; k++)
|
||||
fdash[k] = (float) style->dash[k % style->num_dashes];
|
||||
|
||||
CGContextSetLineDash (surface->cgContext, style->dash_offset, fdash, max_dashes);
|
||||
if (fdash != sdash)
|
||||
free (fdash);
|
||||
}
|
||||
@ -1328,7 +1379,9 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
||||
|
||||
stroke.cgContext = surface->cgContext;
|
||||
stroke.ctm_inverse = ctm_inverse;
|
||||
_cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
rv = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
if (rv)
|
||||
goto BAIL;
|
||||
|
||||
if (action == DO_SOLID || action == DO_PATTERN) {
|
||||
CGContextStrokePath (surface->cgContext);
|
||||
@ -1352,6 +1405,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
||||
rv = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
BAIL:
|
||||
_cairo_quartz_teardown_source (surface, source);
|
||||
|
||||
CGContextRestoreGState (surface->cgContext);
|
||||
@ -1369,6 +1423,9 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
ATSUFontID fid;
|
||||
ATSFontRef atsfref;
|
||||
CGFontRef cgfref;
|
||||
CGAffineTransform cairoTextTransform, textTransform, ctm;
|
||||
// XXXtodo/perf: stack storage for glyphs/sizes
|
||||
#define STATIC_BUF_SIZE 64
|
||||
@ -1401,15 +1458,18 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
CGContextSetTextDrawingMode (surface->cgContext, kCGTextClip);
|
||||
} else {
|
||||
/* Unsupported */
|
||||
CGContextRestoreGState (surface->cgContext);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
rv = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
|
||||
|
||||
/* this doesn't addref */
|
||||
CGFontRef cgfref = _cairo_atsui_scaled_font_get_cg_font_ref (scaled_font);
|
||||
fid = _cairo_atsui_scaled_font_get_atsu_font_id (scaled_font);
|
||||
atsfref = FMGetATSFontRefFromFont (fid);
|
||||
cgfref = CGFontCreateWithPlatformFont (&atsfref);
|
||||
|
||||
CGContextSetFont (surface->cgContext, cgfref);
|
||||
CGFontRelease (cgfref);
|
||||
|
||||
/* So this should include the size; I don't know if I need to extract the
|
||||
* size from this and call CGContextSetFontSize.. will I get crappy hinting
|
||||
@ -1439,7 +1499,16 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
|
||||
if (num_glyphs > STATIC_BUF_SIZE) {
|
||||
cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof(CGGlyph));
|
||||
if (cg_glyphs == NULL) {
|
||||
rv = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
cg_advances = (CGSize*) _cairo_malloc_ab (num_glyphs, sizeof(CGSize));
|
||||
if (cg_advances == NULL) {
|
||||
rv = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
xprev = glyphs[0].x;
|
||||
@ -1470,11 +1539,6 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
cg_advances,
|
||||
num_glyphs);
|
||||
|
||||
if (cg_glyphs != &glyphs_static[0]) {
|
||||
free (cg_glyphs);
|
||||
free (cg_advances);
|
||||
}
|
||||
|
||||
if (action == DO_IMAGE) {
|
||||
CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
|
||||
if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) {
|
||||
@ -1487,6 +1551,15 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
CGContextDrawShading (surface->cgContext, surface->sourceShading);
|
||||
}
|
||||
|
||||
BAIL:
|
||||
if (cg_advances != &cg_advances_static[0]) {
|
||||
free (cg_advances);
|
||||
}
|
||||
|
||||
if (cg_glyphs != &glyphs_static[0]) {
|
||||
free (cg_glyphs);
|
||||
}
|
||||
|
||||
_cairo_quartz_teardown_source (surface, source);
|
||||
|
||||
CGContextRestoreGState (surface->cgContext);
|
||||
@ -1495,6 +1568,45 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||
}
|
||||
#endif /* CAIRO_HAS_ATSUI_FONT */
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_surface_pattern_t *mask)
|
||||
{
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_quartz_surface_t *quartz_surf;
|
||||
CGRect rect;
|
||||
CGImageRef img;
|
||||
cairo_surface_t *pat_surf = mask->surface;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_surface_get_extents (pat_surf, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_quartz_surface_to_quartz (NULL, pat_surf, &quartz_surf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
img = CGBitmapContextCreateImage (quartz_surf->cgContext);
|
||||
if (!img) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
rect = CGRectMake (-mask->base.matrix.x0, -mask->base.matrix.y0, extents.width, extents.height);
|
||||
CGContextSaveGState (surface->cgContext);
|
||||
CGContextClipToMask (surface->cgContext, rect, img);
|
||||
status = _cairo_quartz_surface_paint (surface, op, source);
|
||||
|
||||
CGContextRestoreGState (surface->cgContext);
|
||||
CGImageRelease (img);
|
||||
BAIL:
|
||||
cairo_surface_destroy ((cairo_surface_t*) quartz_surf);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
@ -1511,6 +1623,10 @@ _cairo_quartz_surface_mask (void *abstract_surface,
|
||||
cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
|
||||
|
||||
CGContextSetAlpha (surface->cgContext, solid_mask->color.alpha);
|
||||
} else if (CGContextClipToMask &&
|
||||
mask->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
||||
mask->extend == CAIRO_EXTEND_NONE) {
|
||||
return _cairo_quartz_surface_mask_with_surface (surface, op, source, (cairo_surface_pattern_t *) mask);
|
||||
} else {
|
||||
/* So, CGContextClipToMask is not present in 10.3.9, so we're
|
||||
* doomed; if we have imageData, we can do fallback, otherwise
|
||||
@ -1542,6 +1658,7 @@ _cairo_quartz_surface_intersect_clip_path (void *abstract_surface,
|
||||
{
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||
quartz_stroke_t stroke;
|
||||
cairo_status_t status;
|
||||
|
||||
ND((stderr, "%p _cairo_quartz_surface_intersect_clip_path path: %p\n", surface, path));
|
||||
|
||||
@ -1559,7 +1676,13 @@ _cairo_quartz_surface_intersect_clip_path (void *abstract_surface,
|
||||
CGContextBeginPath (surface->cgContext);
|
||||
stroke.cgContext = surface->cgContext;
|
||||
stroke.ctm_inverse = NULL;
|
||||
_cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
|
||||
/* path must not be empty. */
|
||||
CGContextMoveToPoint (surface->cgContext, 0, 0);
|
||||
status = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (fill_rule == CAIRO_FILL_RULE_WINDING)
|
||||
CGContextClip (surface->cgContext);
|
||||
else
|
||||
@ -1794,6 +1917,7 @@ cairo_quartz_surface_create (cairo_format_t format,
|
||||
width, height);
|
||||
if (!surf) {
|
||||
CGContextRelease (cgc);
|
||||
free (imageData);
|
||||
// create_internal will have set an error
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
66
mozilla/gfx/cairo/cairo/src/cairo-reference-count-private.h
Normal file
66
mozilla/gfx/cairo/cairo/src/cairo-reference-count-private.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_REFRENCE_COUNT_PRIVATE_H
|
||||
#define CAIRO_REFRENCE_COUNT_PRIVATE_H
|
||||
|
||||
#include "cairo-atomic-private.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
/* Encapsulate operations on the object's reference count */
|
||||
typedef struct {
|
||||
cairo_atomic_int_t ref_count;
|
||||
} cairo_reference_count_t;
|
||||
|
||||
#define _cairo_reference_count_inc(RC) _cairo_atomic_int_inc (&(RC)->ref_count)
|
||||
#define _cairo_reference_count_dec_and_test(RC) _cairo_atomic_int_dec_and_test (&(RC)->ref_count)
|
||||
|
||||
#define CAIRO_REFERENCE_COUNT_INIT(RC, VALUE) ((RC)->ref_count = (VALUE))
|
||||
|
||||
#define CAIRO_REFERENCE_COUNT_GET_VALUE(RC) _cairo_atomic_int_get (&(RC)->ref_count)
|
||||
#define CAIRO_REFERENCE_COUNT_SET_VALUE(RC, VALUE) _cairo_atomic_int_set (&(RC)->ref_count, (VALUE))
|
||||
|
||||
#define CAIRO_REFERENCE_COUNT_INVALID_VALUE ((cairo_atomic_int_t) -1)
|
||||
#define CAIRO_REFERENCE_COUNT_INVALID {CAIRO_REFERENCE_COUNT_INVALID_VALUE}
|
||||
|
||||
#define CAIRO_REFERENCE_COUNT_IS_INVALID(RC) (CAIRO_REFERENCE_COUNT_GET_VALUE (RC) == CAIRO_REFERENCE_COUNT_INVALID_VALUE)
|
||||
|
||||
#define CAIRO_REFERENCE_COUNT_HAS_REFERENCE(RC) (CAIRO_REFERENCE_COUNT_GET_VALUE (RC) > 0)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif
|
||||
@ -39,6 +39,8 @@
|
||||
|
||||
#include <pixman.h>
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
/* cairo_region_t is defined in cairoint.h */
|
||||
|
||||
struct _cairo_region {
|
||||
|
||||
@ -67,7 +67,7 @@ _cairo_region_init_boxes (cairo_region_t *region,
|
||||
if (count > ARRAY_LENGTH(stack_pboxes)) {
|
||||
pboxes = _cairo_malloc_ab (count, sizeof(pixman_box16_t));
|
||||
if (pboxes == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
@ -78,7 +78,7 @@ _cairo_region_init_boxes (cairo_region_t *region,
|
||||
}
|
||||
|
||||
if (!pixman_region_init_rects (®ion->rgn, pboxes, count))
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (pboxes != stack_pboxes)
|
||||
free (pboxes);
|
||||
@ -96,7 +96,7 @@ cairo_int_status_t
|
||||
_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
|
||||
{
|
||||
if (!pixman_region_copy (&dst->rgn, &src->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -125,7 +125,7 @@ _cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t
|
||||
|
||||
cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
|
||||
if (cboxes == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
for (i = 0; i < nboxes; i++) {
|
||||
cboxes[i].p1.x = pboxes[i].x1;
|
||||
@ -168,7 +168,7 @@ cairo_int_status_t
|
||||
_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
{
|
||||
if (!pixman_region_subtract (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -177,7 +177,7 @@ cairo_int_status_t
|
||||
_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
{
|
||||
if (!pixman_region_intersect (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -190,7 +190,7 @@ _cairo_region_union_rect (cairo_region_t *dst,
|
||||
if (!pixman_region_union_rect (&dst->rgn, &src->rgn,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-mutex-type-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
|
||||
struct _cairo_scaled_font {
|
||||
/* For most cairo objects, the rule for multiple threads is that
|
||||
@ -79,7 +80,7 @@ struct _cairo_scaled_font {
|
||||
|
||||
/* useful bits for _cairo_scaled_font_nil */
|
||||
cairo_status_t status;
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
/* hash key members */
|
||||
|
||||
@ -188,7 +188,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
cairo_scaled_font_subsets_glyph_t *subset_glyph_ret);
|
||||
|
||||
typedef void
|
||||
typedef cairo_status_t
|
||||
(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset,
|
||||
void *closure);
|
||||
|
||||
@ -262,6 +262,21 @@ _cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure);
|
||||
|
||||
/**
|
||||
* _cairo_scaled_font_subset_create_glyph_names:
|
||||
* @font_subsets: a #cairo_scaled_font_subsets_t
|
||||
*
|
||||
* Create an array of strings containing the glyph name for each glyph
|
||||
* in @font_subsets. The array as store in font_subsets->glyph_names.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful,
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED if the font backend does not support
|
||||
* mapping the glyph indices to unicode characters. Possible errors
|
||||
* include CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset);
|
||||
|
||||
typedef struct _cairo_cff_subset {
|
||||
char *base_font;
|
||||
int *widths;
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
@ -95,10 +96,16 @@ typedef struct _cairo_sub_font_collection {
|
||||
|
||||
unsigned int subset_id;
|
||||
|
||||
cairo_status_t status;
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback;
|
||||
void *font_subset_callback_closure;
|
||||
} cairo_sub_font_collection_t;
|
||||
|
||||
typedef struct _cairo_string_entry {
|
||||
cairo_hash_entry_t base;
|
||||
char *string;
|
||||
} cairo_string_entry_t;
|
||||
|
||||
static void
|
||||
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
|
||||
unsigned long scaled_font_glyph_index)
|
||||
@ -124,8 +131,10 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
|
||||
cairo_sub_font_glyph_t *sub_font_glyph;
|
||||
|
||||
sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
|
||||
if (sub_font_glyph == NULL)
|
||||
if (sub_font_glyph == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index);
|
||||
sub_font_glyph->subset_id = subset_id;
|
||||
@ -214,8 +223,10 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
|
||||
cairo_sub_font_t *sub_font;
|
||||
|
||||
sub_font = malloc (sizeof (cairo_sub_font_t));
|
||||
if (sub_font == NULL)
|
||||
if (sub_font == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sub_font->is_scaled = is_scaled;
|
||||
sub_font->is_composite = is_composite;
|
||||
@ -264,7 +275,7 @@ _cairo_sub_font_pluck (void *entry, void *closure)
|
||||
_cairo_sub_font_destroy (sub_font);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
static cairo_bool_t
|
||||
_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
cairo_scaled_font_subsets_glyph_t *subset_glyph)
|
||||
@ -282,10 +293,10 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
||||
subset_glyph->is_composite = sub_font->is_composite;
|
||||
subset_glyph->x_advance = sub_font_glyph->x_advance;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -321,10 +332,18 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
|
||||
|
||||
sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
|
||||
sub_font->current_subset,
|
||||
sub_font->num_glyphs_in_current_subset++,
|
||||
sub_font->num_glyphs_in_current_subset,
|
||||
scaled_glyph->metrics.x_advance);
|
||||
if (sub_font_glyph == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
|
||||
if (status) {
|
||||
_cairo_sub_font_glyph_destroy (sub_font_glyph);
|
||||
return status;
|
||||
}
|
||||
|
||||
sub_font->num_glyphs_in_current_subset++;
|
||||
|
||||
if (sub_font->is_scaled)
|
||||
{
|
||||
@ -336,12 +355,6 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
|
||||
if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_unscaled_subset_used)
|
||||
sub_font->parent->max_glyphs_per_unscaled_subset_used = sub_font->num_glyphs_in_current_subset;
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
|
||||
if (status) {
|
||||
_cairo_sub_font_glyph_destroy (sub_font_glyph);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
subset_glyph->font_id = sub_font->font_id;
|
||||
@ -363,6 +376,9 @@ _cairo_sub_font_collect (void *entry, void *closure)
|
||||
int i;
|
||||
unsigned int j;
|
||||
|
||||
if (collection->status)
|
||||
return;
|
||||
|
||||
for (i = 0; i <= sub_font->current_subset; i++) {
|
||||
collection->subset_id = i;
|
||||
|
||||
@ -378,6 +394,10 @@ _cairo_sub_font_collect (void *entry, void *closure)
|
||||
|
||||
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
|
||||
_cairo_sub_font_glyph_collect, collection);
|
||||
if (collection->status)
|
||||
break;
|
||||
if (collection->num_glyphs == 0)
|
||||
continue;
|
||||
|
||||
/* Ensure the resulting array has no uninitialized holes */
|
||||
assert (collection->num_glyphs == collection->max_glyph + 1);
|
||||
@ -388,6 +408,7 @@ _cairo_sub_font_collect (void *entry, void *closure)
|
||||
subset.subset_id = i;
|
||||
subset.glyphs = collection->glyphs;
|
||||
subset.num_glyphs = collection->num_glyphs;
|
||||
subset.glyph_names = NULL;
|
||||
/* No need to check for out of memory here. If to_unicode is NULL, the PDF
|
||||
* surface does not emit an ToUnicode stream */
|
||||
subset.to_unicode = _cairo_malloc_ab (collection->num_glyphs, sizeof (unsigned long));
|
||||
@ -397,11 +418,20 @@ _cairo_sub_font_collect (void *entry, void *closure)
|
||||
subset.to_unicode[j] = 0xfffd;
|
||||
}
|
||||
}
|
||||
(collection->font_subset_callback) (&subset,
|
||||
collection->status = (collection->font_subset_callback) (&subset,
|
||||
collection->font_subset_callback_closure);
|
||||
|
||||
if (subset.to_unicode != NULL)
|
||||
free (subset.to_unicode);
|
||||
|
||||
if (subset.glyph_names != NULL) {
|
||||
for (j = 0; j < collection->num_glyphs; j++)
|
||||
free (subset.glyph_names[j]);
|
||||
free (subset.glyph_names);
|
||||
}
|
||||
|
||||
if (collection->status)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,8 +441,10 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type)
|
||||
cairo_scaled_font_subsets_t *subsets;
|
||||
|
||||
subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
|
||||
if (subsets == NULL)
|
||||
if (subsets == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsets->type = type;
|
||||
subsets->max_glyphs_per_unscaled_subset_used = 0;
|
||||
@ -487,10 +519,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
if (_cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
status = _cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
subset_glyph);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
subset_glyph))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -501,10 +532,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
if (_cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
status = _cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
subset_glyph);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
subset_glyph))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -551,13 +581,13 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
|
||||
sub_font = _cairo_sub_font_create (subsets,
|
||||
unscaled_font,
|
||||
subsets->num_sub_fonts++,
|
||||
subsets->num_sub_fonts,
|
||||
max_glyphs,
|
||||
subset_glyph->is_scaled,
|
||||
subset_glyph->is_composite);
|
||||
if (sub_font == NULL) {
|
||||
cairo_scaled_font_destroy (unscaled_font);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
|
||||
@ -566,6 +596,8 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
_cairo_sub_font_destroy (sub_font);
|
||||
return status;
|
||||
}
|
||||
|
||||
subsets->num_sub_fonts++;
|
||||
}
|
||||
} else {
|
||||
/* No path available. Add to scaled subset. */
|
||||
@ -583,13 +615,13 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
|
||||
sub_font = _cairo_sub_font_create (subsets,
|
||||
cairo_scaled_font_reference (scaled_font),
|
||||
subsets->num_sub_fonts++,
|
||||
subsets->num_sub_fonts,
|
||||
max_glyphs,
|
||||
subset_glyph->is_scaled,
|
||||
subset_glyph->is_composite);
|
||||
if (sub_font == NULL) {
|
||||
cairo_scaled_font_destroy (scaled_font);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
|
||||
@ -598,6 +630,8 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
_cairo_sub_font_destroy (sub_font);
|
||||
return status;
|
||||
}
|
||||
|
||||
subsets->num_sub_fonts++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -624,10 +658,11 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
|
||||
|
||||
collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
|
||||
if (collection.glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
collection.font_subset_callback = font_subset_callback;
|
||||
collection.font_subset_callback_closure = closure;
|
||||
collection.status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (is_scaled)
|
||||
_cairo_hash_table_foreach (font_subsets->scaled_sub_fonts,
|
||||
@ -638,10 +673,10 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
|
||||
|
||||
free (collection.glyphs);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return collection.status;
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *font_subsets,
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure)
|
||||
@ -652,7 +687,7 @@ _cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *fon
|
||||
TRUE);
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets,
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure)
|
||||
@ -662,3 +697,149 @@ _cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *fo
|
||||
closure,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_string_equal (const void *key_a, const void *key_b)
|
||||
{
|
||||
const cairo_string_entry_t *a = key_a;
|
||||
const cairo_string_entry_t *b = key_b;
|
||||
|
||||
if (strcmp (a->string, b->string) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_string_init_key (cairo_string_entry_t *key, char *s)
|
||||
{
|
||||
unsigned long sum = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < strlen(s); i++)
|
||||
sum += s[i];
|
||||
key->base.hash = sum;
|
||||
key->string = s;
|
||||
}
|
||||
|
||||
static cairo_string_entry_t *
|
||||
create_string_entry (char *s)
|
||||
{
|
||||
cairo_string_entry_t *entry;
|
||||
|
||||
entry = malloc (sizeof (cairo_string_entry_t));
|
||||
if (entry == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_cairo_string_init_key (entry, s);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset)
|
||||
{
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
unsigned int i;
|
||||
cairo_status_t status;
|
||||
cairo_hash_table_t *names;
|
||||
cairo_string_entry_t key, *entry;
|
||||
char buf[30];
|
||||
|
||||
if (subset->to_unicode == NULL) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (_cairo_truetype_create_glyph_to_unicode_map (subset) != CAIRO_STATUS_SUCCESS) {
|
||||
backend = subset->scaled_font->backend;
|
||||
if (backend->map_glyphs_to_unicode == NULL) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
backend->map_glyphs_to_unicode (subset->scaled_font, subset);
|
||||
}
|
||||
|
||||
subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *));
|
||||
|
||||
names = _cairo_hash_table_create (_cairo_string_equal);
|
||||
if (names == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL1;
|
||||
}
|
||||
|
||||
subset->glyph_names[0] = strdup (".notdef");
|
||||
if (subset->glyph_names[0] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL1;
|
||||
}
|
||||
|
||||
entry = create_string_entry (subset->glyph_names[0]);
|
||||
if (entry == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL2;
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (names, &entry->base);
|
||||
if (status) {
|
||||
free (entry);
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
for (i = 0; i < subset->num_glyphs; i++) {
|
||||
if (subset->to_unicode[i] <= 0xffff) {
|
||||
snprintf (buf, sizeof(buf), "uni%04X", (unsigned int)(subset->to_unicode[i]));
|
||||
_cairo_string_init_key (&key, buf);
|
||||
if (_cairo_hash_table_lookup (names, &key.base,
|
||||
(cairo_hash_entry_t **) &entry)) {
|
||||
snprintf (buf, sizeof(buf), "g%d", i);
|
||||
}
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "g%d", i);
|
||||
}
|
||||
|
||||
subset->glyph_names[i] = strdup (buf);
|
||||
if (subset->glyph_names[i] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
entry = create_string_entry (subset->glyph_names[i]);
|
||||
if (entry == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (names, &entry->base);
|
||||
if (status) {
|
||||
free (entry);
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
CLEANUP_HASH:
|
||||
while (1) {
|
||||
entry = _cairo_hash_table_random_entry (names, NULL);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
_cairo_hash_table_remove (names, (cairo_hash_entry_t *) entry);
|
||||
free (entry);
|
||||
}
|
||||
_cairo_hash_table_destroy (names);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
FAIL2:
|
||||
for (i = 0; i < subset->num_glyphs; i++) {
|
||||
if (subset->glyph_names[i] != NULL)
|
||||
free (subset->glyph_names[i]);
|
||||
}
|
||||
|
||||
FAIL1:
|
||||
free (subset->glyph_names);
|
||||
subset->glyph_names = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -177,10 +177,11 @@ _cairo_scaled_glyph_destroy (void *abstract_glyph)
|
||||
free (scaled_glyph);
|
||||
}
|
||||
|
||||
#define ZOMBIE 0
|
||||
const cairo_scaled_font_t _cairo_scaled_font_nil = {
|
||||
{ 0 }, /* hash_entry */
|
||||
{ ZOMBIE }, /* hash_entry */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
NULL, /* font_face */
|
||||
{ 1., 0., 0., 1., 0, 0}, /* font_matrix */
|
||||
@ -204,27 +205,31 @@ const cairo_scaled_font_t _cairo_scaled_font_nil = {
|
||||
* @status: a status value indicating an error, (eg. not
|
||||
* CAIRO_STATUS_SUCCESS)
|
||||
*
|
||||
* Sets scaled_font->status to @status and calls _cairo_error;
|
||||
* Atomically sets scaled_font->status to @status and calls _cairo_error;
|
||||
*
|
||||
* All assignments of an error status to scaled_font->status should happen
|
||||
* through _cairo_scaled_font_set_error() or else _cairo_error() should be
|
||||
* called immediately after the assignment.
|
||||
* through _cairo_scaled_font_set_error(). Note that due to the nature of
|
||||
* the atomic operation, it is not safe to call this function on the nil
|
||||
* objects.
|
||||
*
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
*
|
||||
* Return value: the error status.
|
||||
**/
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
|
||||
cairo_status_t status)
|
||||
{
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. It also avoids attempting
|
||||
* to write to read-only data (eg. from a nil scaled_font). */
|
||||
if (scaled_font->status == CAIRO_STATUS_SUCCESS)
|
||||
scaled_font->status = status;
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
_cairo_error (status);
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&scaled_font->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +246,7 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
|
||||
cairo_font_type_t
|
||||
cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
|
||||
return CAIRO_FONT_TYPE_TOY;
|
||||
|
||||
return scaled_font->backend->type;
|
||||
@ -324,6 +329,7 @@ _cairo_scaled_font_map_lock (void)
|
||||
cairo_scaled_font_map = NULL;
|
||||
CLEANUP_MUTEX_LOCK:
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -352,7 +358,7 @@ _cairo_scaled_font_map_destroy (void)
|
||||
/* We should only get here through the reset_static_data path
|
||||
* and there had better not be any active references at that
|
||||
* point. */
|
||||
assert (scaled_font->ref_count == 0);
|
||||
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
|
||||
_cairo_hash_table_remove (font_map->hash_table,
|
||||
&scaled_font->hash_entry);
|
||||
_cairo_scaled_font_fini (scaled_font);
|
||||
@ -418,6 +424,7 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
hash ^= cairo_font_options_hash (&scaled_font->options);
|
||||
|
||||
assert (hash != ZOMBIE);
|
||||
scaled_font->hash_entry.hash = hash;
|
||||
}
|
||||
|
||||
@ -481,9 +488,9 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
|
||||
_cairo_scaled_glyph_destroy,
|
||||
MAX_GLYPHS_CACHED_PER_FONT);
|
||||
if (scaled_font->glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
scaled_font->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1);
|
||||
|
||||
_cairo_user_data_array_init (&scaled_font->user_data);
|
||||
|
||||
@ -598,6 +605,9 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
|
||||
|
||||
if (! _cairo_matrix_is_invertible (font_matrix))
|
||||
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
|
||||
|
||||
font_map = _cairo_scaled_font_map_lock ();
|
||||
if (font_map == NULL)
|
||||
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
|
||||
@ -613,7 +623,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
* been found in font_map->holdovers, (which means this caching is
|
||||
* actually working). So now we remove it from the holdovers
|
||||
* array. */
|
||||
if (scaled_font->ref_count == 0) {
|
||||
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < font_map->num_holdovers; i++)
|
||||
@ -635,13 +645,14 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
* than calling into cairo_scaled_font_reference), since we
|
||||
* must modify the reference count while our lock is still
|
||||
* held. */
|
||||
scaled_font->ref_count++;
|
||||
_cairo_reference_count_inc (&scaled_font->ref_count);
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
return scaled_font;
|
||||
}
|
||||
|
||||
/* the font has been put into an error status - abandon the cache */
|
||||
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
|
||||
scaled_font->hash_entry.hash = ZOMBIE;
|
||||
}
|
||||
|
||||
/* Otherwise create it and insert it into the hash table. */
|
||||
@ -649,6 +660,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
ctm, options, &scaled_font);
|
||||
if (status) {
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
status = _cairo_font_face_set_error (font_face, status);
|
||||
return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
|
||||
}
|
||||
|
||||
@ -686,16 +698,13 @@ slim_hidden_def (cairo_scaled_font_create);
|
||||
cairo_scaled_font_t *
|
||||
cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
if (scaled_font == NULL || scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (scaled_font == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
|
||||
return scaled_font;
|
||||
|
||||
_cairo_scaled_font_map_lock ();
|
||||
{
|
||||
assert (scaled_font->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
|
||||
|
||||
scaled_font->ref_count++;
|
||||
}
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
_cairo_reference_count_inc (&scaled_font->ref_count);
|
||||
|
||||
return scaled_font;
|
||||
}
|
||||
@ -715,26 +724,27 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
cairo_scaled_font_map_t *font_map;
|
||||
cairo_scaled_font_t *lru = NULL;
|
||||
|
||||
if (scaled_font == NULL || scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (scaled_font == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
|
||||
return;
|
||||
|
||||
font_map = _cairo_scaled_font_map_lock ();
|
||||
{
|
||||
assert (font_map != NULL);
|
||||
assert (font_map != NULL);
|
||||
|
||||
assert (scaled_font->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
|
||||
|
||||
if (--(scaled_font->ref_count) == 0)
|
||||
{
|
||||
if (_cairo_reference_count_dec_and_test (&scaled_font->ref_count)) {
|
||||
if (scaled_font->hash_entry.hash != ZOMBIE) {
|
||||
/* Rather than immediately destroying this object, we put it into
|
||||
* the font_map->holdovers array in case it will get used again
|
||||
* soon. To make room for it, we do actually destroy the
|
||||
* least-recently-used holdover.
|
||||
* soon (and is why we must hold the lock over the atomic op on
|
||||
* the reference count). To make room for it, we do actually
|
||||
* destroy the least-recently-used holdover.
|
||||
*/
|
||||
if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS)
|
||||
{
|
||||
lru = font_map->holdovers[0];
|
||||
assert (lru->ref_count == 0);
|
||||
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&lru->ref_count));
|
||||
|
||||
_cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry);
|
||||
|
||||
@ -746,7 +756,8 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
|
||||
font_map->holdovers[font_map->num_holdovers] = scaled_font;
|
||||
font_map->num_holdovers++;
|
||||
}
|
||||
} else
|
||||
lru = scaled_font;
|
||||
}
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
|
||||
@ -777,10 +788,11 @@ slim_hidden_def (cairo_scaled_font_destroy);
|
||||
unsigned int
|
||||
cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
if (scaled_font == NULL || scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (scaled_font == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
|
||||
return 0;
|
||||
|
||||
return scaled_font->ref_count;
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&scaled_font->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -829,8 +841,8 @@ cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return _cairo_user_data_array_set_data (&scaled_font->user_data,
|
||||
key, user_data, destroy);
|
||||
@ -890,7 +902,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);
|
||||
if (status) {
|
||||
_cairo_scaled_font_set_error (scaled_font, status);
|
||||
status = _cairo_scaled_font_set_error (scaled_font, status);
|
||||
return;
|
||||
}
|
||||
cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);
|
||||
@ -927,10 +939,18 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
||||
cairo_bool_t visible = FALSE;
|
||||
cairo_scaled_glyph_t *scaled_glyph = NULL;
|
||||
|
||||
if (scaled_font->status)
|
||||
if (scaled_font->status) {
|
||||
extents->x_bearing = 0.0;
|
||||
extents->y_bearing = 0.0;
|
||||
extents->width = 0.0;
|
||||
extents->height = 0.0;
|
||||
extents->x_advance = 0.0;
|
||||
extents->y_advance = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_LOCK (scaled_font->mutex);
|
||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
double left, top, right, bottom;
|
||||
@ -940,7 +960,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (status) {
|
||||
_cairo_scaled_font_set_error (scaled_font, status);
|
||||
status = _cairo_scaled_font_set_error (scaled_font, status);
|
||||
goto UNLOCK;
|
||||
}
|
||||
|
||||
@ -997,6 +1017,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
||||
}
|
||||
|
||||
UNLOCK:
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_glyph_extents);
|
||||
@ -1011,9 +1032,13 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
{
|
||||
int i;
|
||||
uint32_t *ucs4 = NULL;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_status_t status;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
status = scaled_font->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (utf8[0] == '\0') {
|
||||
*num_glyphs = 0;
|
||||
*glyphs = NULL;
|
||||
@ -1021,6 +1046,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_LOCK (scaled_font->mutex);
|
||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||
|
||||
if (scaled_font->backend->text_to_glyphs) {
|
||||
status = scaled_font->backend->text_to_glyphs (scaled_font,
|
||||
@ -1038,7 +1064,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
*glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
|
||||
|
||||
if (*glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
@ -1063,6 +1089,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
}
|
||||
|
||||
DONE:
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
|
||||
|
||||
if (ucs4)
|
||||
@ -1098,10 +1125,8 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (status) {
|
||||
_cairo_scaled_font_set_error (scaled_font, status);
|
||||
return status;
|
||||
}
|
||||
if (status)
|
||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||
|
||||
/* glyph images are snapped to pixel locations */
|
||||
x = _cairo_lround (glyphs[i].x);
|
||||
@ -1145,6 +1170,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_surface_t *mask = NULL;
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
int i;
|
||||
|
||||
/* These operators aren't interpreted the same way by the backends;
|
||||
@ -1167,7 +1193,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
width, height,
|
||||
glyphs, num_glyphs);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||
}
|
||||
|
||||
/* Font display routine either does not exist or failed. */
|
||||
@ -1237,27 +1263,23 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
goto CLEANUP_MASK;
|
||||
}
|
||||
|
||||
if (mask != NULL) {
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
_cairo_pattern_init_for_surface (&mask_pattern, mask);
|
||||
|
||||
_cairo_pattern_init_for_surface (&mask_pattern, mask);
|
||||
status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
|
||||
surface,
|
||||
source_x, source_y,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
|
||||
surface,
|
||||
source_x, source_y,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
_cairo_pattern_fini (&mask_pattern.base);
|
||||
}
|
||||
_cairo_pattern_fini (&mask_pattern.base);
|
||||
|
||||
CLEANUP_MASK:
|
||||
_cairo_cache_thaw (scaled_font->glyphs);
|
||||
|
||||
if (mask != NULL)
|
||||
cairo_surface_destroy (mask);
|
||||
return status;
|
||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||
}
|
||||
|
||||
typedef struct _cairo_scaled_glyph_path_closure {
|
||||
@ -1376,12 +1398,15 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
|
||||
double xoff, yoff;
|
||||
|
||||
if (mask->format == CAIRO_FORMAT_A1)
|
||||
a1_mask = mask;
|
||||
a1_mask = (cairo_image_surface_t *) cairo_surface_reference (&mask->base);
|
||||
else
|
||||
a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
|
||||
|
||||
if (cairo_surface_status (&a1_mask->base))
|
||||
return cairo_surface_status (&a1_mask->base);
|
||||
status = cairo_surface_status (&a1_mask->base);
|
||||
if (status) {
|
||||
cairo_surface_destroy (&a1_mask->base);
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
|
||||
|
||||
@ -1394,16 +1419,16 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
|
||||
status = _add_unit_rectangle_to_path (path,
|
||||
x - xoff, y - yoff);
|
||||
if (status)
|
||||
return status;
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a1_mask != mask)
|
||||
cairo_surface_destroy (&a1_mask->base);
|
||||
BAIL:
|
||||
cairo_surface_destroy (&a1_mask->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1417,10 +1442,12 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
cairo_scaled_glyph_path_closure_t closure;
|
||||
cairo_path_fixed_t *glyph_path;
|
||||
|
||||
if (scaled_font->status)
|
||||
return scaled_font->status;
|
||||
status = scaled_font->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
closure.path = path;
|
||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
@ -1431,7 +1458,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
glyph_path = scaled_glyph->path;
|
||||
else if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
goto BAIL;
|
||||
|
||||
/* If the font is incapable of providing a path, then we'll
|
||||
* have to trace our own from a surface. */
|
||||
@ -1441,16 +1468,18 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
return status;
|
||||
goto BAIL;
|
||||
|
||||
glyph_path = _cairo_path_fixed_create ();
|
||||
if (glyph_path == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (glyph_path == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
|
||||
if (status) {
|
||||
_cairo_path_fixed_destroy (glyph_path);
|
||||
return status;
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1468,10 +1497,12 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
_cairo_path_fixed_destroy (glyph_path);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
goto BAIL;
|
||||
}
|
||||
BAIL:
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1628,7 +1659,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
*/
|
||||
scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t));
|
||||
if (scaled_glyph == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
@ -1679,7 +1710,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
if (status) {
|
||||
/* It's not an error for the backend to not support the info we want. */
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
_cairo_scaled_font_set_error (scaled_font, status);
|
||||
status = _cairo_scaled_font_set_error (scaled_font, status);
|
||||
*scaled_glyph_ret = NULL;
|
||||
} else {
|
||||
*scaled_glyph_ret = scaled_glyph;
|
||||
|
||||
@ -355,8 +355,11 @@ _cairo_skip_list_insert (cairo_skip_list_t *list, void *data, int unique)
|
||||
}
|
||||
|
||||
data_and_elt = alloc_node_for_level (list, level);
|
||||
if (data_and_elt == NULL)
|
||||
if (data_and_elt == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (data_and_elt, data, list->data_size);
|
||||
elt = (skip_elt_t *) (data_and_elt + list->data_size);
|
||||
|
||||
|
||||
@ -40,45 +40,45 @@ static cairo_status_t
|
||||
_cairo_spline_grow (cairo_spline_t *spline);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *point);
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, const cairo_point_t *point);
|
||||
|
||||
static void
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result);
|
||||
_lerp_half (const cairo_point_t *a, const cairo_point_t *b, cairo_point_t *result);
|
||||
|
||||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2);
|
||||
_de_casteljau (cairo_spline_knots_t *s1, cairo_spline_knots_t *s2);
|
||||
|
||||
static double
|
||||
_cairo_spline_error_squared (cairo_spline_t *spline);
|
||||
_cairo_spline_error_squared (const cairo_spline_knots_t *spline);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_decompose_into (cairo_spline_t *spline, double tolerance_squared, cairo_spline_t *result);
|
||||
_cairo_spline_decompose_into (cairo_spline_knots_t *spline, double tolerance_squared, cairo_spline_t *result);
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_spline_init (cairo_spline_t *spline,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
const cairo_point_t *a, const cairo_point_t *b,
|
||||
const cairo_point_t *c, const cairo_point_t *d)
|
||||
{
|
||||
spline->a = *a;
|
||||
spline->b = *b;
|
||||
spline->c = *c;
|
||||
spline->d = *d;
|
||||
spline->knots.a = *a;
|
||||
spline->knots.b = *b;
|
||||
spline->knots.c = *c;
|
||||
spline->knots.d = *d;
|
||||
|
||||
if (a->x != b->x || a->y != b->y)
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->b);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.b);
|
||||
else if (a->x != c->x || a->y != c->y)
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->c);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.c);
|
||||
else if (a->x != d->x || a->y != d->y)
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->d);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.d);
|
||||
else
|
||||
return CAIRO_INT_STATUS_DEGENERATE;
|
||||
|
||||
if (c->x != d->x || c->y != d->y)
|
||||
_cairo_slope_init (&spline->final_slope, &spline->c, &spline->d);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->knots.c, &spline->knots.d);
|
||||
else if (b->x != d->x || b->y != d->y)
|
||||
_cairo_slope_init (&spline->final_slope, &spline->b, &spline->d);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->knots.b, &spline->knots.d);
|
||||
else
|
||||
_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->knots.a, &spline->knots.d);
|
||||
|
||||
spline->points = spline->points_embedded;
|
||||
spline->points_size = ARRAY_LENGTH (spline->points_embedded);
|
||||
@ -113,12 +113,12 @@ _cairo_spline_grow (cairo_spline_t *spline)
|
||||
if (new_points)
|
||||
memcpy (new_points, spline->points, old_size * sizeof (cairo_point_t));
|
||||
} else {
|
||||
new_points = realloc (spline->points, new_size * sizeof (cairo_point_t));
|
||||
new_points = _cairo_realloc_ab (spline->points,
|
||||
new_size, sizeof (cairo_point_t));
|
||||
}
|
||||
|
||||
if (new_points == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (new_points == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
spline->points = new_points;
|
||||
spline->points_size = new_size;
|
||||
@ -127,7 +127,7 @@ _cairo_spline_grow (cairo_spline_t *spline)
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *point)
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, const cairo_point_t *point)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_point_t *prev;
|
||||
@ -151,96 +151,92 @@ _cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *point)
|
||||
}
|
||||
|
||||
static void
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result)
|
||||
_lerp_half (const cairo_point_t *a, const cairo_point_t *b, cairo_point_t *result)
|
||||
{
|
||||
result->x = a->x + ((b->x - a->x) >> 1);
|
||||
result->y = a->y + ((b->y - a->y) >> 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2)
|
||||
_de_casteljau (cairo_spline_knots_t *s1, cairo_spline_knots_t *s2)
|
||||
{
|
||||
cairo_point_t ab, bc, cd;
|
||||
cairo_point_t abbc, bccd;
|
||||
cairo_point_t final;
|
||||
|
||||
_lerp_half (&spline->a, &spline->b, &ab);
|
||||
_lerp_half (&spline->b, &spline->c, &bc);
|
||||
_lerp_half (&spline->c, &spline->d, &cd);
|
||||
_lerp_half (&s1->a, &s1->b, &ab);
|
||||
_lerp_half (&s1->b, &s1->c, &bc);
|
||||
_lerp_half (&s1->c, &s1->d, &cd);
|
||||
_lerp_half (&ab, &bc, &abbc);
|
||||
_lerp_half (&bc, &cd, &bccd);
|
||||
_lerp_half (&abbc, &bccd, &final);
|
||||
|
||||
s1->a = spline->a;
|
||||
s1->b = ab;
|
||||
s1->c = abbc;
|
||||
s1->d = final;
|
||||
|
||||
s2->a = final;
|
||||
s2->b = bccd;
|
||||
s2->c = cd;
|
||||
s2->d = spline->d;
|
||||
s2->d = s1->d;
|
||||
|
||||
s1->b = ab;
|
||||
s1->c = abbc;
|
||||
s1->d = final;
|
||||
}
|
||||
|
||||
/* Return an upper bound on the error (squared) that could result from
|
||||
* approximating a spline as a line segment connecting the two endpoints. */
|
||||
static double
|
||||
_PointDistanceSquaredToPoint (cairo_point_t *a, cairo_point_t *b)
|
||||
_cairo_spline_error_squared (const cairo_spline_knots_t *knots)
|
||||
{
|
||||
double dx = _cairo_fixed_to_double (b->x - a->x);
|
||||
double dy = _cairo_fixed_to_double (b->y - a->y);
|
||||
double bdx, bdy, berr;
|
||||
double cdx, cdy, cerr;
|
||||
|
||||
return dx*dx + dy*dy;
|
||||
}
|
||||
/* Intersection point (px):
|
||||
* px = p1 + u(p2 - p1)
|
||||
* (p - px) ∙ (p2 - p1) = 0
|
||||
* Thus:
|
||||
* u = ((p - p1) ∙ (p2 - p1)) / ∥p2 - p1∥²;
|
||||
*/
|
||||
bdx = _cairo_fixed_to_double (knots->b.x - knots->a.x);
|
||||
bdy = _cairo_fixed_to_double (knots->b.y - knots->a.y);
|
||||
|
||||
static double
|
||||
_PointDistanceSquaredToSegment (cairo_point_t *p, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
double u;
|
||||
double dx, dy;
|
||||
double pdx, pdy;
|
||||
cairo_point_t px;
|
||||
cdx = _cairo_fixed_to_double (knots->c.x - knots->a.x);
|
||||
cdy = _cairo_fixed_to_double (knots->c.y - knots->a.y);
|
||||
|
||||
/* intersection point (px):
|
||||
if (knots->a.x != knots->d.x || knots->a.y != knots->d.y) {
|
||||
double dx, dy, u, v;
|
||||
|
||||
px = p1 + u(p2 - p1)
|
||||
(p - px) . (p2 - p1) = 0
|
||||
dx = _cairo_fixed_to_double (knots->d.x - knots->a.x);
|
||||
dy = _cairo_fixed_to_double (knots->d.y - knots->a.y);
|
||||
v = dx * dx + dy * dy;
|
||||
|
||||
Thus:
|
||||
u = bdx * dx + bdy * dy;
|
||||
if (u <= 0) {
|
||||
/* bdx -= 0;
|
||||
* bdy -= 0;
|
||||
*/
|
||||
} else if (u >= v) {
|
||||
bdx -= dx;
|
||||
bdy -= dy;
|
||||
} else {
|
||||
bdx -= u/v * dx;
|
||||
bdy -= u/v * dy;
|
||||
}
|
||||
|
||||
u = ((p - p1) . (p2 - p1)) / (||(p2 - p1)|| ^ 2);
|
||||
*/
|
||||
|
||||
dx = _cairo_fixed_to_double (p2->x - p1->x);
|
||||
dy = _cairo_fixed_to_double (p2->y - p1->y);
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
return _PointDistanceSquaredToPoint (p, p1);
|
||||
|
||||
pdx = _cairo_fixed_to_double (p->x - p1->x);
|
||||
pdy = _cairo_fixed_to_double (p->y - p1->y);
|
||||
|
||||
u = (pdx * dx + pdy * dy) / (dx*dx + dy*dy);
|
||||
|
||||
if (u <= 0)
|
||||
return _PointDistanceSquaredToPoint (p, p1);
|
||||
else if (u >= 1)
|
||||
return _PointDistanceSquaredToPoint (p, p2);
|
||||
|
||||
px.x = p1->x + u * (p2->x - p1->x);
|
||||
px.y = p1->y + u * (p2->y - p1->y);
|
||||
|
||||
return _PointDistanceSquaredToPoint (p, &px);
|
||||
}
|
||||
|
||||
/* Return an upper bound on the error (squared) that could result from approximating
|
||||
a spline as a line segment connecting the two endpoints */
|
||||
static double
|
||||
_cairo_spline_error_squared (cairo_spline_t *spline)
|
||||
{
|
||||
double berr, cerr;
|
||||
|
||||
berr = _PointDistanceSquaredToSegment (&spline->b, &spline->a, &spline->d);
|
||||
cerr = _PointDistanceSquaredToSegment (&spline->c, &spline->a, &spline->d);
|
||||
u = cdx * dx + cdy * dy;
|
||||
if (u <= 0) {
|
||||
/* cdx -= 0;
|
||||
* cdy -= 0;
|
||||
*/
|
||||
} else if (u >= v) {
|
||||
cdx -= dx;
|
||||
cdy -= dy;
|
||||
} else {
|
||||
cdx -= u/v * dx;
|
||||
cdy -= u/v * dy;
|
||||
}
|
||||
}
|
||||
|
||||
berr = bdx * bdx + bdy * bdy;
|
||||
cerr = cdx * cdx + cdy * cdy;
|
||||
if (berr > cerr)
|
||||
return berr;
|
||||
else
|
||||
@ -248,18 +244,17 @@ _cairo_spline_error_squared (cairo_spline_t *spline)
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_decompose_into (cairo_spline_t *spline, double tolerance_squared, cairo_spline_t *result)
|
||||
_cairo_spline_decompose_into (cairo_spline_knots_t *s1, double tolerance_squared, cairo_spline_t *result)
|
||||
{
|
||||
cairo_spline_knots_t s2;
|
||||
cairo_status_t status;
|
||||
cairo_spline_t s1, s2;
|
||||
|
||||
if (_cairo_spline_error_squared (spline) < tolerance_squared) {
|
||||
return _cairo_spline_add_point (result, &spline->a);
|
||||
}
|
||||
if (_cairo_spline_error_squared (s1) < tolerance_squared)
|
||||
return _cairo_spline_add_point (result, &s1->a);
|
||||
|
||||
_de_casteljau (spline, &s1, &s2);
|
||||
_de_casteljau (s1, &s2);
|
||||
|
||||
status = _cairo_spline_decompose_into (&s1, tolerance_squared, result);
|
||||
status = _cairo_spline_decompose_into (s1, tolerance_squared, result);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
@ -274,15 +269,17 @@ cairo_status_t
|
||||
_cairo_spline_decompose (cairo_spline_t *spline, double tolerance)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_spline_knots_t s1;
|
||||
|
||||
/* reset the spline, but keep the buffer */
|
||||
spline->num_points = 0;
|
||||
|
||||
status = _cairo_spline_decompose_into (spline, tolerance * tolerance, spline);
|
||||
s1 = spline->knots;
|
||||
status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_spline_add_point (spline, &spline->d);
|
||||
status = _cairo_spline_add_point (spline, &spline->knots.d);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
||||
} else {
|
||||
style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
|
||||
if (style->dash == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (style->dash, other->dash,
|
||||
style->num_dashes * sizeof (double));
|
||||
|
||||
@ -125,7 +125,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
||||
extents->width,
|
||||
extents->height);
|
||||
if (mask->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return mask->status;
|
||||
|
||||
status = (*draw_func) (draw_closure, CAIRO_OPERATOR_ADD,
|
||||
NULL, mask,
|
||||
@ -211,7 +211,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
|
||||
extents->width,
|
||||
extents->height);
|
||||
if (intermediate->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return intermediate->status;
|
||||
|
||||
/* Initialize the intermediate surface from the destination surface
|
||||
*/
|
||||
@ -1049,8 +1049,11 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
|
||||
snapshot = cairo_image_surface_create (image->format,
|
||||
image->width,
|
||||
image->height);
|
||||
if (cairo_surface_status (snapshot))
|
||||
if (cairo_surface_status (snapshot)) {
|
||||
_cairo_surface_release_source_image (surface,
|
||||
image, &image_extra);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
|
||||
|
||||
@ -1065,14 +1068,14 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
|
||||
image->height);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
_cairo_surface_release_source_image (surface,
|
||||
image, &image_extra);
|
||||
|
||||
if (status) {
|
||||
cairo_surface_destroy (snapshot);
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_release_source_image (surface,
|
||||
image, image_extra);
|
||||
|
||||
snapshot->device_transform = surface->device_transform;
|
||||
snapshot->device_transform_inverse = surface->device_transform_inverse;
|
||||
|
||||
@ -1171,7 +1174,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
|
||||
if (offset_rects == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
@ -1227,7 +1230,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
offset_traps = _cairo_malloc_ab (num_traps, sizeof (cairo_trapezoid_t));
|
||||
if (!offset_traps) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "cairo.h"
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
|
||||
struct _cairo_surface {
|
||||
const cairo_surface_backend_t *backend;
|
||||
@ -52,7 +53,7 @@ struct _cairo_surface {
|
||||
|
||||
cairo_content_t content;
|
||||
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t finished;
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
@ -46,7 +46,7 @@ const cairo_surface_t name = { \
|
||||
&cairo_image_surface_backend, /* backend */ \
|
||||
CAIRO_SURFACE_TYPE_IMAGE, \
|
||||
CAIRO_CONTENT_COLOR, \
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */ \
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \
|
||||
status, /* status */ \
|
||||
FALSE, /* finished */ \
|
||||
{ 0, /* size */ \
|
||||
@ -94,27 +94,31 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
|
||||
* @status: a status value indicating an error, (eg. not
|
||||
* CAIRO_STATUS_SUCCESS)
|
||||
*
|
||||
* Sets surface->status to @status and calls _cairo_error;
|
||||
* Atomically sets surface->status to @status and calls _cairo_error;
|
||||
*
|
||||
* All assignments of an error status to surface->status should happen
|
||||
* through _cairo_surface_set_error() or else _cairo_error() should be
|
||||
* called immediately after the assignment.
|
||||
* through _cairo_surface_set_error(). Note that due to the nature of
|
||||
* the atomic operation, it is not safe to call this function on the
|
||||
* nil objects.
|
||||
*
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
*
|
||||
* Return value: the error status.
|
||||
**/
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_surface_set_error (cairo_surface_t *surface,
|
||||
cairo_status_t status)
|
||||
{
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. It also avoids attempting
|
||||
* to write to read-only data (eg. from a nil surface). */
|
||||
if (surface->status == CAIRO_STATUS_SUCCESS)
|
||||
surface->status = status;
|
||||
if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
_cairo_error (status);
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&surface->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +171,7 @@ slim_hidden_def(cairo_surface_get_content);
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
|
||||
* %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
|
||||
* %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALUE_FORMAT, or
|
||||
* %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
|
||||
* %CAIRO_STATUS_INVALID_VISUAL.
|
||||
**/
|
||||
cairo_status_t
|
||||
@ -188,7 +192,7 @@ _cairo_surface_init (cairo_surface_t *surface,
|
||||
surface->content = content;
|
||||
surface->type = backend->type;
|
||||
|
||||
surface->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
|
||||
surface->status = CAIRO_STATUS_SUCCESS;
|
||||
surface->finished = FALSE;
|
||||
|
||||
@ -288,7 +292,7 @@ cairo_surface_create_similar (cairo_surface_t *other,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
if (! CAIRO_CONTENT_VALID (content)) {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_CONTENT);
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -314,7 +318,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
surface = _cairo_surface_create_similar_scratch (other, content,
|
||||
width, height);
|
||||
if (surface->status) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -322,7 +326,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
source = _cairo_pattern_create_solid (color, content);
|
||||
if (source->status) {
|
||||
cairo_surface_destroy (surface);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
} else
|
||||
@ -338,7 +342,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
|
||||
if (status) {
|
||||
cairo_surface_destroy (surface);
|
||||
_cairo_error (status);
|
||||
_cairo_error_throw (status);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -372,12 +376,13 @@ _cairo_surface_get_clip_mode (cairo_surface_t *surface)
|
||||
cairo_surface_t *
|
||||
cairo_surface_reference (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface == NULL || surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (surface == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return surface;
|
||||
|
||||
assert (surface->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
|
||||
|
||||
surface->ref_count++;
|
||||
_cairo_reference_count_inc (&surface->ref_count);
|
||||
|
||||
return surface;
|
||||
}
|
||||
@ -394,13 +399,13 @@ slim_hidden_def (cairo_surface_reference);
|
||||
void
|
||||
cairo_surface_destroy (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface == NULL || surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (surface == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return;
|
||||
|
||||
assert (surface->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
|
||||
|
||||
surface->ref_count--;
|
||||
if (surface->ref_count)
|
||||
if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
|
||||
return;
|
||||
|
||||
if (! surface->finished)
|
||||
@ -422,17 +427,18 @@ slim_hidden_def(cairo_surface_destroy);
|
||||
cairo_status_t
|
||||
_cairo_surface_reset (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface == NULL || surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (surface == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
assert (surface->ref_count == 1);
|
||||
assert (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count) == 1);
|
||||
|
||||
_cairo_user_data_array_fini (&surface->user_data);
|
||||
|
||||
if (surface->backend->reset != NULL) {
|
||||
cairo_status_t status = surface->backend->reset (surface);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
_cairo_surface_init (surface, surface->backend, surface->content);
|
||||
@ -454,10 +460,11 @@ _cairo_surface_reset (cairo_surface_t *surface)
|
||||
unsigned int
|
||||
cairo_surface_get_reference_count (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface == NULL || surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (surface == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return 0;
|
||||
|
||||
return surface->ref_count;
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -486,11 +493,11 @@ cairo_surface_finish (cairo_surface_t *surface)
|
||||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
if (surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -502,14 +509,14 @@ cairo_surface_finish (cairo_surface_t *surface)
|
||||
if (!surface->status && surface->backend->flush) {
|
||||
status = surface->backend->flush (surface);
|
||||
if (status) {
|
||||
_cairo_surface_set_error (surface, status);
|
||||
status = _cairo_surface_set_error (surface, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status = surface->backend->finish (surface);
|
||||
if (status)
|
||||
_cairo_surface_set_error (surface, status);
|
||||
status = _cairo_surface_set_error (surface, status);
|
||||
|
||||
surface->finished = TRUE;
|
||||
}
|
||||
@ -557,8 +564,8 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (surface->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return _cairo_user_data_array_set_data (&surface->user_data,
|
||||
key, user_data, destroy);
|
||||
@ -583,6 +590,19 @@ void
|
||||
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface,
|
||||
CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (options) {
|
||||
surface->has_font_options = TRUE;
|
||||
_cairo_font_options_init_copy (&surface->font_options, options);
|
||||
@ -638,21 +658,20 @@ slim_hidden_def (cairo_surface_get_font_options);
|
||||
void
|
||||
cairo_surface_flush (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->backend->flush) {
|
||||
cairo_status_t status;
|
||||
|
||||
status = surface->backend->flush (surface);
|
||||
|
||||
if (status)
|
||||
_cairo_surface_set_error (surface, status);
|
||||
status = _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,13 +714,15 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -713,8 +734,6 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
surface->current_clip_serial = -1;
|
||||
|
||||
if (surface->backend->mark_dirty_rectangle) {
|
||||
cairo_status_t status;
|
||||
|
||||
/* XXX: FRAGILE: We're ignoring the scaling component of
|
||||
* device_transform here. I don't know what the right thing to
|
||||
* do would actually be if there were some scaling here, but
|
||||
@ -726,7 +745,7 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
width, height);
|
||||
|
||||
if (status)
|
||||
_cairo_surface_set_error (surface, status);
|
||||
status = _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
|
||||
@ -756,13 +775,15 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
|
||||
double sx,
|
||||
double sy)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -796,13 +817,15 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
||||
double x_offset,
|
||||
double y_offset)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -872,6 +895,18 @@ cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
|
||||
double x_pixels_per_inch,
|
||||
double y_pixels_per_inch)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
surface->x_fallback_resolution = x_pixels_per_inch;
|
||||
surface->y_fallback_resolution = y_pixels_per_inch;
|
||||
}
|
||||
@ -907,8 +942,9 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
||||
{
|
||||
assert (!surface->finished);
|
||||
|
||||
return surface->backend->acquire_source_image (surface,
|
||||
image_out, image_extra);
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->acquire_source_image (surface,
|
||||
image_out, image_extra));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -969,9 +1005,12 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
{
|
||||
assert (!surface->finished);
|
||||
|
||||
return surface->backend->acquire_dest_image (surface,
|
||||
interest_rect,
|
||||
image_out, image_rect, image_extra);
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->acquire_dest_image (surface,
|
||||
interest_rect,
|
||||
image_out,
|
||||
image_rect,
|
||||
image_extra));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1034,7 +1073,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
||||
void *image_extra;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (surface->backend->clone_similar) {
|
||||
status = surface->backend->clone_similar (surface, src, src_x, src_y,
|
||||
@ -1162,7 +1201,7 @@ _cairo_surface_composite (cairo_operator_t op,
|
||||
return dst->status;
|
||||
|
||||
if (dst->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->composite) {
|
||||
status = dst->backend->composite (op,
|
||||
@ -1172,15 +1211,16 @@ _cairo_surface_composite (cairo_operator_t op,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_composite (op,
|
||||
return _cairo_surface_set_error (dst,
|
||||
_cairo_surface_fallback_composite (op,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
width, height));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1215,7 +1255,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
@ -1245,46 +1285,54 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
int num_boxes;
|
||||
cairo_box_int_t *boxes;
|
||||
cairo_box_int_t *boxes = NULL;
|
||||
cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
|
||||
cairo_rectangle_int_t *rects;
|
||||
cairo_rectangle_int_t *rects = stack_rects;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
num_boxes = _cairo_region_num_boxes (region);
|
||||
|
||||
if (num_boxes == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
rects = stack_rects;
|
||||
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
|
||||
if (!rects) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
/* handle the common case of a single box without allocation */
|
||||
if (num_boxes > 1) {
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].x = boxes[i].p1.x;
|
||||
rects[i].y = boxes[i].p1.y;
|
||||
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
|
||||
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
|
||||
}
|
||||
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (num_boxes,
|
||||
sizeof (cairo_rectangle_int_t));
|
||||
if (!rects) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return _cairo_surface_set_error (surface,
|
||||
CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].x = boxes[i].p1.x;
|
||||
rects[i].y = boxes[i].p1.y;
|
||||
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
|
||||
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
|
||||
}
|
||||
} else
|
||||
_cairo_region_get_extents (region, &rects[0]);
|
||||
|
||||
status = _cairo_surface_fill_rectangles (surface, op,
|
||||
color, rects, num_boxes);
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
if (boxes != NULL)
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free (rects);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1318,7 +1366,7 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (num_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -1327,11 +1375,12 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
status = surface->backend->fill_rectangles (surface, op, color,
|
||||
rects, num_rects);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_fill_rectangles (surface, op, color,
|
||||
rects, num_rects);
|
||||
return _cairo_surface_set_error (surface,
|
||||
_cairo_surface_fallback_fill_rectangles (surface, op, color,
|
||||
rects, num_rects));
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1346,7 +1395,7 @@ _cairo_surface_paint (cairo_surface_t *surface,
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
if (surface->backend->paint) {
|
||||
status = surface->backend->paint (surface, op, &dev_source.base);
|
||||
@ -1359,7 +1408,7 @@ _cairo_surface_paint (cairo_surface_t *surface,
|
||||
FINISH:
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1377,6 +1426,7 @@ _cairo_surface_mask (cairo_surface_t *surface,
|
||||
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
if (status)
|
||||
goto FINISH;
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
|
||||
if (status)
|
||||
goto CLEANUP_SOURCE;
|
||||
@ -1395,7 +1445,7 @@ _cairo_surface_mask (cairo_surface_t *surface,
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
FINISH:
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1424,12 +1474,12 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (stroke_source, surface, &dev_stroke_source.base);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (fill_source, surface, &dev_fill_source.base);
|
||||
if (status) {
|
||||
_cairo_pattern_fini (&dev_stroke_source.base);
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
status = surface->backend->fill_stroke (surface, fill_op, &dev_fill_source.base,
|
||||
@ -1442,19 +1492,21 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
|
||||
_cairo_pattern_fini (&dev_fill_source.base);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
status = _cairo_surface_fill (surface, fill_op, fill_source, path,
|
||||
fill_rule, fill_tolerance, fill_antialias);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
|
||||
stroke_style, stroke_ctm, stroke_ctm_inverse,
|
||||
stroke_tolerance, stroke_antialias);
|
||||
if (status)
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1479,7 +1531,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
if (surface->backend->stroke) {
|
||||
status = surface->backend->stroke (surface, op, &dev_source.base,
|
||||
@ -1501,7 +1553,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
|
||||
_cairo_path_fixed_fini (&real_dev_path);
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1520,7 +1572,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
if (surface->backend->fill) {
|
||||
status = surface->backend->fill (surface, op, &dev_source.base,
|
||||
@ -1538,7 +1590,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
|
||||
FINISH:
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1568,7 +1620,7 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||
return dst->status;
|
||||
|
||||
if (dst->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->composite_trapezoids) {
|
||||
status = dst->backend->composite_trapezoids (op,
|
||||
@ -1579,15 +1631,16 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||
width, height,
|
||||
traps, num_traps);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
|
||||
return _cairo_surface_set_error (dst,
|
||||
_cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
|
||||
antialias,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
traps, num_traps);
|
||||
traps, num_traps));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1610,13 +1663,14 @@ cairo_surface_copy_page (cairo_surface_t *surface)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
/* It's fine if some backends don't implement copy_page */
|
||||
if (surface->backend->copy_page == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return surface->backend->copy_page (surface);
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->copy_page (surface));
|
||||
}
|
||||
slim_hidden_def (cairo_surface_copy_page);
|
||||
|
||||
@ -1639,13 +1693,14 @@ cairo_surface_show_page (cairo_surface_t *surface)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
/* It's fine if some backends don't implement show_page */
|
||||
if (surface->backend->show_page == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return surface->backend->show_page (surface);
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->show_page (surface));
|
||||
}
|
||||
slim_hidden_def (cairo_surface_show_page);
|
||||
|
||||
@ -1705,7 +1760,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
surface->current_clip_serial = 0;
|
||||
|
||||
@ -1716,13 +1771,13 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
|
||||
0,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
if (surface->backend->set_clip_region != NULL) {
|
||||
status = surface->backend->set_clip_region (surface, NULL);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -1749,7 +1804,7 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
assert (surface->backend->set_clip_region != NULL);
|
||||
|
||||
@ -1757,7 +1812,7 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
|
||||
|
||||
status = surface->backend->set_clip_region (surface, region);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
@ -1774,7 +1829,7 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
assert (surface->backend->intersect_clip_path != NULL);
|
||||
|
||||
@ -1784,7 +1839,7 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
|
||||
tolerance,
|
||||
antialias);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1827,7 +1882,7 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
assert (surface->backend->intersect_clip_path != NULL);
|
||||
|
||||
@ -1837,30 +1892,59 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface,
|
||||
0,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
status = _cairo_surface_set_clip_path_recursive (surface, clip_path);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
surface->current_clip_serial = serial;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _cairo_surface_set_empty_clip_path:
|
||||
* @surface: the #cairo_surface_t to set the clip on
|
||||
* @serial: the clip serial number associated with the clip path
|
||||
*
|
||||
* Create an empty clip path, one that represents the entire surface clipped
|
||||
* out, and assigns the given clipping serial to the surface.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_cairo_surface_set_empty_clip_path (cairo_surface_t *surface,
|
||||
unsigned int serial)
|
||||
{
|
||||
cairo_path_fixed_t path;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_path_fixed_init (&path);
|
||||
|
||||
status = surface->backend->intersect_clip_path (surface,
|
||||
&path,
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
0,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
surface->current_clip_serial = serial;
|
||||
|
||||
_cairo_path_fixed_fini (&path);
|
||||
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
||||
{
|
||||
unsigned int serial = 0;
|
||||
|
||||
if (!surface)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (clip) {
|
||||
serial = clip->serial;
|
||||
@ -1874,15 +1958,26 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip) {
|
||||
if (clip->path)
|
||||
return _cairo_surface_set_clip_path (surface,
|
||||
clip->path,
|
||||
clip->serial);
|
||||
if (clip->all_clipped) {
|
||||
if (surface->backend->intersect_clip_path != NULL)
|
||||
return _cairo_surface_set_empty_clip_path (surface,
|
||||
clip->serial);
|
||||
|
||||
if (clip->has_region)
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
&clip->region,
|
||||
clip->serial);
|
||||
if (surface->backend->set_clip_region != NULL)
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
&clip->region,
|
||||
clip->serial);
|
||||
} else {
|
||||
if (clip->path)
|
||||
return _cairo_surface_set_clip_path (surface,
|
||||
clip->path,
|
||||
clip->serial);
|
||||
|
||||
if (clip->has_region)
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
&clip->region,
|
||||
clip->serial);
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_surface_reset_clip (surface);
|
||||
@ -1920,9 +2015,10 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
return surface->backend->get_extents (surface, rectangle);
|
||||
return _cairo_surface_set_error (surface,
|
||||
surface->backend->get_extents (surface, rectangle));
|
||||
}
|
||||
|
||||
/* Note: the backends may modify the contents of the glyph array as long as
|
||||
@ -1955,7 +2051,7 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
||||
surface,
|
||||
&dev_source.base);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
|
||||
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
|
||||
|
||||
@ -1979,7 +2075,7 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
||||
status = cairo_scaled_font_status (dev_scaled_font);
|
||||
if (status) {
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_LOCK (dev_scaled_font->mutex);
|
||||
@ -2003,7 +2099,7 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
||||
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
/* XXX: Previously, we had a function named _cairo_surface_show_glyphs
|
||||
@ -2033,7 +2129,7 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
return dst->status;
|
||||
|
||||
if (dst->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->old_show_glyphs) {
|
||||
status = dst->backend->old_show_glyphs (scaled_font,
|
||||
@ -2045,7 +2141,7 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
} else
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -2092,7 +2188,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
|
||||
!= CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_REGIONS;
|
||||
}
|
||||
|
||||
@ -2106,7 +2202,7 @@ CLEANUP_REGIONS:
|
||||
if (has_clear_region)
|
||||
_cairo_region_fini (&clear_region);
|
||||
|
||||
return status;
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -257,21 +257,17 @@ _cairo_traps_grow (cairo_traps_t *traps)
|
||||
cairo_trapezoid_t *new_traps;
|
||||
int new_size = 2 * MAX (traps->traps_size, 16);
|
||||
|
||||
if (traps->status)
|
||||
return traps->status;
|
||||
|
||||
if (traps->traps == traps->traps_embedded) {
|
||||
new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t));
|
||||
if (new_traps)
|
||||
memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded));
|
||||
} else {
|
||||
new_traps = realloc (traps->traps, new_size * sizeof (cairo_trapezoid_t));
|
||||
new_traps = _cairo_realloc_ab (traps->traps,
|
||||
new_size, sizeof (cairo_trapezoid_t));
|
||||
}
|
||||
|
||||
if (new_traps == NULL) {
|
||||
traps->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return traps->status;
|
||||
}
|
||||
if (new_traps == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
traps->traps = new_traps;
|
||||
traps->traps_size = new_size;
|
||||
@ -614,7 +610,7 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
|
||||
boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_t));
|
||||
|
||||
if (boxes == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
box_count = 0;
|
||||
|
||||
@ -46,10 +46,22 @@ struct subset_glyph {
|
||||
unsigned long location;
|
||||
};
|
||||
|
||||
typedef struct _cairo_truetype_font {
|
||||
typedef struct _cairo_truetype_font cairo_truetype_font_t;
|
||||
|
||||
typedef struct table table_t;
|
||||
struct table {
|
||||
unsigned long tag;
|
||||
cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag);
|
||||
int pos; /* position in the font directory */
|
||||
};
|
||||
|
||||
struct _cairo_truetype_font {
|
||||
|
||||
cairo_scaled_font_subset_t *scaled_font_subset;
|
||||
|
||||
table_t truetype_tables[10];
|
||||
int num_tables;
|
||||
|
||||
struct {
|
||||
char *base_font;
|
||||
unsigned int num_glyphs;
|
||||
@ -70,7 +82,7 @@ typedef struct _cairo_truetype_font {
|
||||
int *parent_to_subset;
|
||||
cairo_status_t status;
|
||||
|
||||
} cairo_truetype_font_t;
|
||||
};
|
||||
|
||||
static int
|
||||
cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
|
||||
@ -78,6 +90,18 @@ cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
|
||||
#define SFNT_VERSION 0x00010000
|
||||
#define SFNT_STRING_MAX_LENGTH 65535
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_truetype_font_set_error (cairo_truetype_font_t *font,
|
||||
cairo_status_t status)
|
||||
{
|
||||
if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
_cairo_status_set_error (&font->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_truetype_font_t **font_return)
|
||||
@ -107,42 +131,51 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
*/
|
||||
|
||||
size = sizeof (tt_head_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0, (unsigned char *) &head,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0,
|
||||
(unsigned char *) &head,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
size = sizeof (tt_maxp_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_maxp, 0, (unsigned char *) &maxp,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_maxp, 0,
|
||||
(unsigned char *) &maxp,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0, (unsigned char *) &hhea,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0,
|
||||
(unsigned char *) &hhea,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
size = 0;
|
||||
if (backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0, NULL,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0,
|
||||
NULL,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
name = malloc(size);
|
||||
if (name == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
|
||||
TT_TAG_name, 0, (unsigned char *) name,
|
||||
TT_TAG_name, 0,
|
||||
(unsigned char *) name,
|
||||
&size);
|
||||
if (status)
|
||||
goto fail0;
|
||||
|
||||
font = malloc (sizeof (cairo_truetype_font_t));
|
||||
if (font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
@ -159,13 +192,13 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
|
||||
if (font->glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
|
||||
if (font->parent_to_subset == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
@ -209,7 +242,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
if (font->base.base_font == NULL) {
|
||||
font->base.base_font = malloc (30);
|
||||
if (font->base.base_font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
@ -227,7 +260,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
|
||||
if (font->base.widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
@ -258,7 +291,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
if (name)
|
||||
free (name);
|
||||
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -280,9 +313,12 @@ cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t *font,
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
status = _cairo_array_allocate (&font->output, length, (void **) buffer);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -294,9 +330,12 @@ cairo_truetype_font_write (cairo_truetype_font_t *font,
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
status = _cairo_array_append_multiple (&font->output, data, length);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -307,6 +346,9 @@ cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
|
||||
{
|
||||
uint16_t be16_value;
|
||||
|
||||
if (font->status)
|
||||
return;
|
||||
|
||||
be16_value = cpu_to_be16 (value);
|
||||
cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
|
||||
}
|
||||
@ -317,6 +359,9 @@ cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
|
||||
{
|
||||
uint32_t be32_value;
|
||||
|
||||
if (font->status)
|
||||
return;
|
||||
|
||||
be32_value = cpu_to_be32 (value);
|
||||
cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
|
||||
}
|
||||
@ -345,12 +390,15 @@ cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
|
||||
{
|
||||
status = _cairo_array_append (&font->string_offsets,
|
||||
&font->last_boundary);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
font->last_offset = font->last_boundary;
|
||||
}
|
||||
@ -416,21 +464,23 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = 0;
|
||||
if (font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, buffer, &size);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -446,6 +496,9 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
|
||||
unsigned short flags;
|
||||
unsigned short index;
|
||||
|
||||
if (font->status)
|
||||
return;
|
||||
|
||||
glyph_data = (tt_glyph_data_t *) buffer;
|
||||
if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
|
||||
return;
|
||||
@ -483,30 +536,31 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
|
||||
uint16_t *short_offsets;
|
||||
uint32_t *long_offsets;
|
||||
} u;
|
||||
cairo_status_t status;
|
||||
|
||||
size = sizeof (tt_head_t);
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0,
|
||||
(unsigned char*) &header, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = sizeof (tt_head_t);
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0,
|
||||
(unsigned char*) &header, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
if (be16_to_cpu (header.index_to_loc_format) == 0)
|
||||
size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
|
||||
else
|
||||
size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
|
||||
|
||||
u.bytes = malloc (size);
|
||||
if (u.bytes == NULL) {
|
||||
font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return font->status;
|
||||
}
|
||||
if (u.bytes == NULL)
|
||||
return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_loca, 0, u.bytes, &size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_loca, 0, u.bytes, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
start_offset = _cairo_array_num_elements (&font->output);
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
@ -524,21 +578,21 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
|
||||
|
||||
next = cairo_truetype_font_align_output (font);
|
||||
|
||||
font->status = cairo_truetype_font_check_boundary (font, next);
|
||||
if (font->status)
|
||||
break;
|
||||
status = cairo_truetype_font_check_boundary (font, next);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
font->glyphs[i].location = next - start_offset;
|
||||
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (font->status)
|
||||
break;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
if (size != 0) {
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_glyf, begin, buffer, &size);
|
||||
if (font->status)
|
||||
break;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_glyf, begin, buffer, &size);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
cairo_truetype_font_remap_composite_glyph (font, buffer);
|
||||
}
|
||||
@ -547,9 +601,11 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
|
||||
font->glyphs[i].location =
|
||||
cairo_truetype_font_align_output (font) - start_offset;
|
||||
|
||||
status = font->status;
|
||||
FAIL:
|
||||
free (u.bytes);
|
||||
|
||||
return font->status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -558,27 +614,31 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
|
||||
{
|
||||
unsigned char *buffer;
|
||||
unsigned long size;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = 0;
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, NULL, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
font->status = font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
|
||||
tag, 0, buffer, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, buffer, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
/* set checkSumAdjustment to 0 for table checksum calcualtion */
|
||||
*(uint32_t *)(buffer + 8) = 0;
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -586,20 +646,24 @@ cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long
|
||||
{
|
||||
tt_hhea_t *hhea;
|
||||
unsigned long size;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) hhea, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) hhea, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -613,54 +677,58 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
|
||||
unsigned int i;
|
||||
tt_hhea_t hhea;
|
||||
int num_hmetrics;
|
||||
cairo_status_t status;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0,
|
||||
(unsigned char*) &hhea, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = sizeof (tt_hhea_t);
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hhea, 0,
|
||||
(unsigned char*) &hhea, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
long_entry_size = 2 * sizeof (int16_t);
|
||||
short_entry_size = sizeof (int16_t);
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size,
|
||||
(unsigned char **) &p);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font,
|
||||
long_entry_size,
|
||||
(unsigned char **) &p);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
if (font->glyphs[i].parent_index < num_hmetrics) {
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
font->glyphs[i].parent_index * long_entry_size,
|
||||
(unsigned char *) p, &long_entry_size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
font->glyphs[i].parent_index * long_entry_size,
|
||||
(unsigned char *) p, &long_entry_size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
(num_hmetrics - 1) * long_entry_size,
|
||||
(unsigned char *) p, &short_entry_size) != CAIRO_STATUS_SUCCESS) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return font->status;
|
||||
}
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
num_hmetrics * long_entry_size +
|
||||
(font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
|
||||
(unsigned char *) (p + 1), &short_entry_size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
(num_hmetrics - 1) * long_entry_size,
|
||||
(unsigned char *) p, &short_entry_size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_hmtx,
|
||||
num_hmetrics * long_entry_size +
|
||||
(font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
|
||||
(unsigned char *) (p + 1), &short_entry_size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
}
|
||||
font->base.widths[i] = be16_to_cpu (p[0]);
|
||||
}
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -670,14 +738,18 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
|
||||
unsigned int i;
|
||||
tt_head_t header;
|
||||
unsigned long size;
|
||||
cairo_status_t status;
|
||||
|
||||
size = sizeof(tt_head_t);
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0,
|
||||
(unsigned char*) &header, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = sizeof(tt_head_t);
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_head, 0,
|
||||
(unsigned char*) &header, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
if (be16_to_cpu (header.index_to_loc_format) == 0)
|
||||
{
|
||||
for (i = 0; i < font->base.num_glyphs + 1; i++)
|
||||
@ -696,51 +768,26 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
|
||||
{
|
||||
tt_maxp_t *maxp;
|
||||
unsigned long size;
|
||||
cairo_status_t status;
|
||||
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
size = sizeof (tt_maxp_t);
|
||||
font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) maxp, &size);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
tag, 0, (unsigned char *) maxp, &size);
|
||||
if (status)
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct table table_t;
|
||||
struct table {
|
||||
unsigned long tag;
|
||||
cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag);
|
||||
int pos; /* position in the font directory */
|
||||
};
|
||||
|
||||
static const table_t truetype_tables[] = {
|
||||
/* As we write out the glyf table we remap composite glyphs.
|
||||
* Remapping composite glyphs will reference the sub glyphs the
|
||||
* composite glyph is made up of. That needs to be done first so
|
||||
* we have all the glyphs in the subset before going further.
|
||||
*
|
||||
* The third column in this table is the order in which the
|
||||
* directory entries will appear in the table directory.
|
||||
* The table directory must be sorted in tag order. */
|
||||
{ TT_TAG_glyf, cairo_truetype_font_write_glyf_table, 3 },
|
||||
{ TT_TAG_cmap, cairo_truetype_font_write_cmap_table, 0 },
|
||||
{ TT_TAG_cvt, cairo_truetype_font_write_generic_table, 1 },
|
||||
{ TT_TAG_fpgm, cairo_truetype_font_write_generic_table, 2 },
|
||||
{ TT_TAG_head, cairo_truetype_font_write_head_table, 4 },
|
||||
{ TT_TAG_hhea, cairo_truetype_font_write_hhea_table, 5 },
|
||||
{ TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, 6 },
|
||||
{ TT_TAG_loca, cairo_truetype_font_write_loca_table, 7 },
|
||||
{ TT_TAG_maxp, cairo_truetype_font_write_maxp_table, 8 },
|
||||
{ TT_TAG_name, cairo_truetype_font_write_generic_table, 9 },
|
||||
{ TT_TAG_prep, cairo_truetype_font_write_generic_table, 10 },
|
||||
};
|
||||
|
||||
static cairo_status_t
|
||||
cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
|
||||
{
|
||||
@ -748,20 +795,21 @@ cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
|
||||
unsigned char *table_buffer;
|
||||
size_t table_buffer_length;
|
||||
unsigned short search_range, entry_selector, range_shift;
|
||||
int num_tables;
|
||||
|
||||
num_tables = ARRAY_LENGTH (truetype_tables);
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
search_range = 1;
|
||||
entry_selector = 0;
|
||||
while (search_range * 2 <= num_tables) {
|
||||
while (search_range * 2 <= font->num_tables) {
|
||||
search_range *= 2;
|
||||
entry_selector++;
|
||||
}
|
||||
search_range *= 16;
|
||||
range_shift = num_tables * 16 - search_range;
|
||||
range_shift = font->num_tables * 16 - search_range;
|
||||
|
||||
cairo_truetype_font_write_be32 (font, SFNT_VERSION);
|
||||
cairo_truetype_font_write_be16 (font, num_tables);
|
||||
cairo_truetype_font_write_be16 (font, font->num_tables);
|
||||
cairo_truetype_font_write_be16 (font, search_range);
|
||||
cairo_truetype_font_write_be16 (font, entry_selector);
|
||||
cairo_truetype_font_write_be16 (font, range_shift);
|
||||
@ -769,13 +817,13 @@ cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
|
||||
/* Allocate space for the table directory. Each directory entry
|
||||
* will be filled in by cairo_truetype_font_update_entry() after
|
||||
* the table is written. */
|
||||
table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
|
||||
table_buffer_length = font->num_tables * 16;
|
||||
status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
|
||||
&table_buffer);
|
||||
if (status)
|
||||
return status;
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
@ -824,28 +872,31 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font,
|
||||
cairo_status_t status;
|
||||
unsigned long start, end, next;
|
||||
uint32_t checksum, *checksum_location;
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
if (cairo_truetype_font_write_offset_table (font))
|
||||
goto fail;
|
||||
if (font->status)
|
||||
return font->status;
|
||||
|
||||
status = cairo_truetype_font_write_offset_table (font);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
start = cairo_truetype_font_align_output (font);
|
||||
end = start;
|
||||
|
||||
end = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
|
||||
if (truetype_tables[i].write (font, truetype_tables[i].tag))
|
||||
goto fail;
|
||||
for (i = 0; i < font->num_tables; i++) {
|
||||
status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
end = _cairo_array_num_elements (&font->output);
|
||||
next = cairo_truetype_font_align_output (font);
|
||||
cairo_truetype_font_update_entry (font, truetype_tables[i].pos, truetype_tables[i].tag,
|
||||
start, end);
|
||||
cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
|
||||
font->truetype_tables[i].tag, start, end);
|
||||
status = cairo_truetype_font_check_boundary (font, next);
|
||||
if (status) {
|
||||
font->status = status;
|
||||
goto fail;
|
||||
}
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
start = next;
|
||||
}
|
||||
@ -863,8 +914,8 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font,
|
||||
else
|
||||
*string_offsets = NULL;
|
||||
|
||||
fail:
|
||||
return font->status;
|
||||
FAIL:
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -879,6 +930,91 @@ cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
|
||||
return font->parent_to_subset[glyph];
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
|
||||
unsigned long tag,
|
||||
cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
|
||||
int pos)
|
||||
{
|
||||
font->truetype_tables[font->num_tables].tag = tag;
|
||||
font->truetype_tables[font->num_tables].write = write;
|
||||
font->truetype_tables[font->num_tables].pos = pos;
|
||||
font->num_tables++;
|
||||
}
|
||||
|
||||
/* cairo_truetype_font_create_truetype_table_list() builds the list of
|
||||
* truetype tables to be embedded in the subsetted font. Each call to
|
||||
* cairo_truetype_font_add_truetype_table() adds a table, the callback
|
||||
* for generating the table, and the position in the table directory
|
||||
* to the truetype_tables array.
|
||||
*
|
||||
* As we write out the glyf table we remap composite glyphs.
|
||||
* Remapping composite glyphs will reference the sub glyphs the
|
||||
* composite glyph is made up of. The "glyf" table callback needs to
|
||||
* be called first so we have all the glyphs in the subset before
|
||||
* going further.
|
||||
*
|
||||
* The order in which tables are added to the truetype_table array
|
||||
* using cairo_truetype_font_add_truetype_table() specifies the order
|
||||
* in which the callback functions will be called.
|
||||
*
|
||||
* The tables in the table directory must be listed in alphabetical
|
||||
* order. The "cvt", "fpgm", and "prep" are optional tables. They
|
||||
* will only be embedded in the subset if they exist in the source
|
||||
* font. The pos parameter of cairo_truetype_font_add_truetype_table()
|
||||
* specifies the position of the table in the table directory.
|
||||
*/
|
||||
static void
|
||||
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
|
||||
{
|
||||
cairo_bool_t has_cvt = FALSE;
|
||||
cairo_bool_t has_fpgm = FALSE;
|
||||
cairo_bool_t has_prep = FALSE;
|
||||
unsigned long size;
|
||||
int pos;
|
||||
|
||||
size = 0;
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_cvt, 0, NULL,
|
||||
&size) == CAIRO_STATUS_SUCCESS)
|
||||
has_cvt = TRUE;
|
||||
|
||||
size = 0;
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_fpgm, 0, NULL,
|
||||
&size) == CAIRO_STATUS_SUCCESS)
|
||||
has_fpgm = TRUE;
|
||||
|
||||
size = 0;
|
||||
if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
|
||||
TT_TAG_prep, 0, NULL,
|
||||
&size) == CAIRO_STATUS_SUCCESS)
|
||||
has_prep = TRUE;
|
||||
|
||||
font->num_tables = 0;
|
||||
pos = 1;
|
||||
if (has_cvt)
|
||||
pos++;
|
||||
if (has_fpgm)
|
||||
pos++;
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
|
||||
|
||||
pos = 0;
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
|
||||
if (has_cvt)
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
|
||||
if (has_fpgm)
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++);
|
||||
pos++;
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++);
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++);
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++);
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++);
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
|
||||
if (has_prep)
|
||||
cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
@ -901,14 +1037,15 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
cairo_truetype_font_use_glyph (font, parent_glyph);
|
||||
}
|
||||
|
||||
cairo_truetype_font_create_truetype_table_list (font);
|
||||
status = cairo_truetype_font_generate (font, &data, &length,
|
||||
&string_offsets, &num_strings);
|
||||
&string_offsets, &num_strings);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
truetype_subset->base_font = strdup (font->base.base_font);
|
||||
if (truetype_subset->base_font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
@ -918,7 +1055,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
truetype_subset->widths = calloc (sizeof (double),
|
||||
font->scaled_font_subset->num_glyphs);
|
||||
if (truetype_subset->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
@ -934,7 +1071,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
if (length) {
|
||||
truetype_subset->data = malloc (length);
|
||||
if (truetype_subset->data == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
@ -947,7 +1084,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
offsets_length = num_strings * sizeof (unsigned long);
|
||||
truetype_subset->string_offsets = malloc (offsets_length);
|
||||
if (truetype_subset->string_offsets == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
@ -971,6 +1108,9 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
|
||||
fail1:
|
||||
cairo_truetype_font_destroy (font);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
status = _cairo_error (status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -987,7 +1127,7 @@ static cairo_int_status_t
|
||||
_cairo_truetype_map_glyphs_to_unicode (cairo_scaled_font_subset_t *font_subset,
|
||||
unsigned long table_offset)
|
||||
{
|
||||
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
cairo_status_t status;
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
tt_segment_map_t *map;
|
||||
char buf[4];
|
||||
@ -1002,12 +1142,12 @@ _cairo_truetype_map_glyphs_to_unicode (cairo_scaled_font_subset_t *font_subset,
|
||||
|
||||
backend = font_subset->scaled_font->backend;
|
||||
size = 4;
|
||||
if (backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, table_offset,
|
||||
(unsigned char *) &buf,
|
||||
&size) != CAIRO_STATUS_SUCCESS) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
status = backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, table_offset,
|
||||
(unsigned char *) &buf,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* All table formats have the same first two words */
|
||||
map = (tt_segment_map_t *) buf;
|
||||
@ -1017,13 +1157,14 @@ _cairo_truetype_map_glyphs_to_unicode (cairo_scaled_font_subset_t *font_subset,
|
||||
size = be16_to_cpu (map->length);
|
||||
map = malloc (size);
|
||||
if (map == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, table_offset,
|
||||
(unsigned char *) map,
|
||||
&size) != CAIRO_STATUS_SUCCESS) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, table_offset,
|
||||
(unsigned char *) map,
|
||||
&size);
|
||||
if (status)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
num_segments = be16_to_cpu (map->segCountX2)/2;
|
||||
end_code = map->endCount;
|
||||
@ -1091,23 +1232,26 @@ _cairo_truetype_create_glyph_to_unicode_map (cairo_scaled_font_subset_t *font_su
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
size = 4;
|
||||
if (backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, 0, (unsigned char *) &buf,
|
||||
&size) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
status = backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, 0,
|
||||
(unsigned char *) &buf,
|
||||
&size);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cmap = (tt_cmap_t *) buf;
|
||||
num_tables = be16_to_cpu (cmap->num_tables);
|
||||
size = 4 + num_tables*sizeof(tt_cmap_index_t);
|
||||
cmap = malloc (size);
|
||||
if (cmap == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, 0, (unsigned char *) cmap,
|
||||
&size) != CAIRO_STATUS_SUCCESS) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = backend->load_truetype_table (font_subset->scaled_font,
|
||||
TT_TAG_cmap, 0,
|
||||
(unsigned char *) cmap,
|
||||
&size);
|
||||
if (status)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Find a table with Unicode mapping */
|
||||
for (i = 0; i < num_tables; i++) {
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
typedef enum {
|
||||
CAIRO_CHARSTRING_TYPE1,
|
||||
CAIRO_CHARSTRING_TYPE2,
|
||||
CAIRO_CHARSTRING_TYPE2
|
||||
} cairo_charstring_type_t;
|
||||
|
||||
typedef struct _cairo_type1_font {
|
||||
@ -81,13 +81,13 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
|
||||
font = calloc (1, sizeof (cairo_type1_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->widths = calloc (scaled_font_subset->num_glyphs,
|
||||
sizeof (int));
|
||||
if (font->widths == NULL) {
|
||||
free (font);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
@ -119,7 +119,7 @@ fail:
|
||||
free (font->widths);
|
||||
free (font);
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Charstring commands. If the high byte is 0 the command is encoded
|
||||
@ -465,7 +465,13 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
||||
goto fail;
|
||||
charstring_encrypt (&data);
|
||||
length = _cairo_array_num_elements (&data);
|
||||
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
|
||||
if (font->scaled_font_subset->glyph_names != NULL) {
|
||||
_cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
|
||||
font->scaled_font_subset->glyph_names[i],
|
||||
length);
|
||||
} else {
|
||||
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
|
||||
}
|
||||
_cairo_output_stream_write (encrypted_output,
|
||||
_cairo_array_index (&data, 0),
|
||||
length);
|
||||
@ -527,8 +533,14 @@ cairo_type1_font_write_header (cairo_type1_font_t *font,
|
||||
"} readonly def\n"
|
||||
"/Encoding 256 array\n"
|
||||
"0 1 255 {1 index exch /.notdef put} for\n");
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
|
||||
for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
if (font->scaled_font_subset->glyph_names != NULL) {
|
||||
_cairo_output_stream_printf (font->output, "dup %d /%s put\n",
|
||||
i, font->scaled_font_subset->glyph_names[i]);
|
||||
} else {
|
||||
_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
|
||||
}
|
||||
}
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"readonly def\n"
|
||||
"currentdict end\n"
|
||||
@ -589,7 +601,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
|
||||
NULL,
|
||||
font);
|
||||
if (encrypted_output == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -729,13 +741,13 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
|
||||
|
||||
type1_subset->base_font = strdup (name);
|
||||
if (type1_subset->base_font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (type1_subset->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
@ -752,7 +764,7 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
|
||||
font->trailer_size;
|
||||
type1_subset->data = malloc (length);
|
||||
if (type1_subset->data == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
memcpy (type1_subset->data,
|
||||
@ -781,7 +793,7 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
|
||||
/* status is already set, ignore further errors */
|
||||
cairo_type1_font_destroy (font);
|
||||
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -829,7 +841,7 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
|
||||
|
||||
type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (type2_subset->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
@ -865,15 +877,14 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
|
||||
type2_subset->ascent = (int) font->y_max;
|
||||
type2_subset->descent = (int) font->y_min;
|
||||
|
||||
cairo_type1_font_destroy (font);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return cairo_type1_font_destroy (font);
|
||||
|
||||
fail2:
|
||||
_cairo_array_fini (&charstring);
|
||||
_cairo_type2_charstrings_fini (type2_subset);
|
||||
fail1:
|
||||
cairo_type1_font_destroy (font);
|
||||
return status;
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -99,8 +99,6 @@ typedef struct _cairo_type1_font_subset {
|
||||
unsigned short eexec_key;
|
||||
cairo_bool_t hex_encode;
|
||||
int hex_column;
|
||||
|
||||
cairo_status_t status;
|
||||
} cairo_type1_font_subset_t;
|
||||
|
||||
|
||||
@ -119,15 +117,25 @@ _cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
|
||||
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
|
||||
if (face == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
/* OpenType/CFF fonts also have a PS_FontInfoRec */
|
||||
#if HAVE_FT_LOAD_SFNT_TABLE
|
||||
if (FT_IS_SFNT (face)) {
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
goto fail1;
|
||||
}
|
||||
#endif
|
||||
|
||||
font = calloc (sizeof (cairo_type1_font_subset_t), 1);
|
||||
if (font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
@ -141,7 +149,7 @@ _cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
|
||||
font->base.descent = face->descender;
|
||||
font->base.base_font = strdup (face->family_name);
|
||||
if (font->base.base_font == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
@ -154,7 +162,7 @@ _cairo_type1_font_subset_create (cairo_unscaled_font_t *unscaled_font,
|
||||
|
||||
font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]);
|
||||
if (font->glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
@ -208,6 +216,9 @@ find_token (const char *buffer, const char *end, const char *token)
|
||||
int i, length;
|
||||
/* FIXME: find substring really must be find_token */
|
||||
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
length = strlen (token);
|
||||
for (i = 0; buffer + i < end - length + 1; i++)
|
||||
if (memcmp (buffer + i, token, length) == 0)
|
||||
@ -247,7 +258,7 @@ cairo_type1_font_subset_find_segments (cairo_type1_font_subset_t *font)
|
||||
} else {
|
||||
eexec_token = find_token ((char *) p, font->type1_end, "eexec");
|
||||
if (eexec_token == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
|
||||
font->header_segment = (char *) p;
|
||||
@ -270,7 +281,7 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
||||
|
||||
start = find_token (font->header_segment, segment_end, "/FontName");
|
||||
if (start == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
_cairo_output_stream_write (font->output, font->header_segment,
|
||||
start - font->header_segment);
|
||||
@ -279,12 +290,12 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
||||
|
||||
end = find_token (start, segment_end, "def");
|
||||
if (end == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
end += 3;
|
||||
|
||||
start = find_token (end, segment_end, "/Encoding");
|
||||
if (start == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
_cairo_output_stream_write (font->output, end, start - end);
|
||||
|
||||
_cairo_output_stream_printf (font->output,
|
||||
@ -302,12 +313,12 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
||||
|
||||
end = find_token (start, segment_end, "def");
|
||||
if (end == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
end += 3;
|
||||
|
||||
_cairo_output_stream_write (font->output, end, segment_end - end);
|
||||
|
||||
return font->status;
|
||||
return font->output->status;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -321,7 +332,7 @@ hex_to_int (int ch)
|
||||
return ch - 'a' + 10;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
|
||||
const char *data, unsigned int length)
|
||||
{
|
||||
@ -354,6 +365,8 @@ cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
|
||||
_cairo_output_stream_write (font->output, digits, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return font->output->status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -369,9 +382,9 @@ cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
|
||||
|
||||
font->cleartext = malloc (font->eexec_segment_size);
|
||||
if (font->cleartext == NULL)
|
||||
return font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
out = font->cleartext;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
out = font->cleartext;
|
||||
while (in < end) {
|
||||
if (font->eexec_segment_is_ascii) {
|
||||
c = *in++;
|
||||
@ -386,10 +399,9 @@ cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
|
||||
|
||||
*out++ = p;
|
||||
}
|
||||
|
||||
font->cleartext_end = out;
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -440,7 +452,7 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
|
||||
FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
|
||||
if (error != 0) {
|
||||
printf ("could not load glyph %d\n", i);
|
||||
return font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
|
||||
@ -448,12 +460,12 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
|
||||
error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
|
||||
if (error != 0) {
|
||||
printf ("could not get glyph name for glyph %d\n", i);
|
||||
return font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
font->glyphs[i].name = strdup (buffer);
|
||||
if (font->glyphs[i].name == NULL)
|
||||
return font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -678,35 +690,38 @@ static const int16_t ps_standard_encoding_offset[256] = {
|
||||
|
||||
#define ps_standard_encoding(index) ((index) ? ps_standard_encoding_symbol+ps_standard_encoding_offset[(index)] : NULL)
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
|
||||
{
|
||||
const char *glyph_name;
|
||||
|
||||
if (index < 0 || index > 255)
|
||||
return;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
glyph_name = ps_standard_encoding(index);
|
||||
if (glyph_name == NULL)
|
||||
return;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
index = cairo_type1_font_subset_lookup_glyph (font,
|
||||
glyph_name,
|
||||
strlen(glyph_name));
|
||||
if (index < 0)
|
||||
return;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
cairo_type1_font_subset_use_glyph (font, index);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define TYPE1_CHARSTRING_COMMAND_ESCAPE (12)
|
||||
#define TYPE1_CHARSTRING_COMMAND_SEAC (32 + 6)
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
||||
const char *name, int name_length,
|
||||
const char *encrypted_charstring, int encrypted_charstring_length)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *charstring;
|
||||
const unsigned char *end;
|
||||
const unsigned char *p;
|
||||
@ -715,7 +730,7 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
||||
|
||||
charstring = malloc (encrypted_charstring_length);
|
||||
if (charstring == NULL)
|
||||
return;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
|
||||
encrypted_charstring,
|
||||
@ -741,8 +756,14 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
||||
* glyph is composed from. All we need to do is to
|
||||
* make sure those glyphs are present in the subset
|
||||
* under their standard names. */
|
||||
use_standard_encoding_glyph (font, stack[3]);
|
||||
use_standard_encoding_glyph (font, stack[4]);
|
||||
status = use_standard_encoding_glyph (font, stack[3]);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = use_standard_encoding_glyph (font, stack[4]);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
sp = 0;
|
||||
break;
|
||||
|
||||
@ -759,35 +780,50 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
||||
}
|
||||
|
||||
free (charstring);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
write_used_glyphs (cairo_type1_font_subset_t *font,
|
||||
const char *name, int name_length,
|
||||
const char *charstring, int charstring_length)
|
||||
{
|
||||
cairo_status_t status;
|
||||
char buffer[256];
|
||||
int length;
|
||||
|
||||
length = snprintf (buffer, sizeof buffer,
|
||||
"/%.*s %d %s ",
|
||||
name_length, name, charstring_length, font->rd);
|
||||
cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
cairo_type1_font_subset_write_encrypted (font,
|
||||
charstring, charstring_length);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_type1_font_subset_write_encrypted (font,
|
||||
charstring,
|
||||
charstring_length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
|
||||
cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef void (*glyph_func_t) (cairo_type1_font_subset_t *font,
|
||||
const char *name, int name_length,
|
||||
const char *charstring, int charstring_length);
|
||||
typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
|
||||
const char *name, int name_length,
|
||||
const char *charstring, int charstring_length);
|
||||
|
||||
static const char *
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
||||
const char *dict_start,
|
||||
const char *dict_end,
|
||||
glyph_func_t func)
|
||||
glyph_func_t func,
|
||||
const char **dict_out)
|
||||
{
|
||||
int charstring_length, name_length, glyph_index;
|
||||
const char *p, *charstring, *name;
|
||||
@ -815,10 +851,8 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
||||
name_length = p - name;
|
||||
|
||||
charstring_length = strtol (p, &end, 10);
|
||||
if (p == end) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (p == end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Skip past -| or RD to binary data. There is exactly one space
|
||||
* between the -| or RD token and the encrypted data, thus '+ 1'. */
|
||||
@ -831,25 +865,31 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
||||
|
||||
/* In case any of the skip_token() calls above reached EOF, p will
|
||||
* be equal to dict_end. */
|
||||
if (p == dict_end) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (p == dict_end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
glyph_index = cairo_type1_font_subset_lookup_glyph (font,
|
||||
name, name_length);
|
||||
if (font->glyphs[glyph_index].subset_index >= 0)
|
||||
func (font, name, name_length, charstring, charstring_length);
|
||||
if (font->glyphs[glyph_index].subset_index >= 0) {
|
||||
cairo_status_t status = func (font,
|
||||
name, name_length,
|
||||
charstring, charstring_length);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
*dict_out = p;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
|
||||
const char *name)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const char *p, *charstrings, *dict_start;
|
||||
const char *closefile_token;
|
||||
char buffer[32], *glyph_count_end;
|
||||
@ -872,88 +912,98 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
|
||||
* conceivably have "/CharStrings" in it, so we might need to skip
|
||||
* this more cleverly. */
|
||||
charstrings = find_token (font->cleartext, font->cleartext_end, "/CharStrings");
|
||||
if (charstrings == NULL) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (charstrings == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Scan past /CharStrings and the integer following it. */
|
||||
p = charstrings + strlen ("/CharStrings");
|
||||
num_charstrings = strtol (p, &glyph_count_end, 10);
|
||||
if (p == glyph_count_end) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (p == glyph_count_end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Look for a '/' which marks the beginning of the first glyph
|
||||
* definition. */
|
||||
for (p = glyph_count_end; p < font->cleartext_end; p++)
|
||||
if (*p == '/')
|
||||
break;
|
||||
if (p == font->cleartext_end) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (p == font->cleartext_end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
dict_start = p;
|
||||
|
||||
if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
|
||||
return NULL;
|
||||
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Now that we have the private dictionary broken down in
|
||||
* sections, do the first pass through the glyph definitions to
|
||||
* figure out which subrs and othersubrs are use and which extra
|
||||
* glyphs may be required by the seac operator. */
|
||||
p = cairo_type1_font_subset_for_each_glyph (font,
|
||||
dict_start,
|
||||
font->cleartext_end,
|
||||
cairo_type1_font_subset_look_for_seac);
|
||||
status = cairo_type1_font_subset_for_each_glyph (font,
|
||||
dict_start,
|
||||
font->cleartext_end,
|
||||
cairo_type1_font_subset_look_for_seac,
|
||||
&p);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
closefile_token = find_token (p, font->cleartext_end, "closefile");
|
||||
if (closefile_token == NULL) {
|
||||
font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return NULL;
|
||||
}
|
||||
if (closefile_token == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
|
||||
return NULL;
|
||||
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* We're ready to start outputting. First write the header,
|
||||
* i.e. the public part of the font dict.*/
|
||||
if (cairo_type1_font_subset_write_header (font, name))
|
||||
return NULL;
|
||||
status = cairo_type1_font_subset_write_header (font, name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->base.header_size = _cairo_output_stream_get_position (font->output);
|
||||
|
||||
|
||||
/* Start outputting the private dict. First output everything up
|
||||
* to the /CharStrings token. */
|
||||
cairo_type1_font_subset_write_encrypted (font, font->cleartext,
|
||||
charstrings - font->cleartext);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
|
||||
charstrings - font->cleartext);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Write out new charstring count */
|
||||
length = snprintf (buffer, sizeof buffer,
|
||||
"/CharStrings %d", font->num_glyphs);
|
||||
cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Write out text between the charstring count and the first
|
||||
* charstring definition */
|
||||
cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
|
||||
dict_start - glyph_count_end);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
|
||||
dict_start - glyph_count_end);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Write out the charstring definitions for each of the glyphs in
|
||||
* the subset. */
|
||||
p = cairo_type1_font_subset_for_each_glyph (font,
|
||||
dict_start,
|
||||
font->cleartext_end,
|
||||
write_used_glyphs);
|
||||
status = cairo_type1_font_subset_for_each_glyph (font,
|
||||
dict_start,
|
||||
font->cleartext_end,
|
||||
write_used_glyphs,
|
||||
&p);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Output what's left between the end of the glyph definitions and
|
||||
* the end of the private dict to the output. */
|
||||
cairo_type1_font_subset_write_encrypted (font, p,
|
||||
closefile_token - p + strlen ("closefile") + 1);
|
||||
status = cairo_type1_font_subset_write_encrypted (font, p,
|
||||
closefile_token - p + strlen ("closefile") + 1);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_write (font->output, "\n", 1);
|
||||
|
||||
return p;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -973,12 +1023,12 @@ cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font)
|
||||
|
||||
cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
|
||||
if (cleartomark_token == NULL)
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
_cairo_output_stream_write (font->output, cleartomark_token,
|
||||
font->type1_end - cleartomark_token);
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -986,21 +1036,22 @@ type1_font_write (void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
cairo_type1_font_subset_t *font = closure;
|
||||
|
||||
font->status =
|
||||
_cairo_array_append_multiple (&font->contents, data, length);
|
||||
|
||||
return font->status;
|
||||
return _cairo_array_append_multiple (&font->contents, data, length);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
|
||||
const char *name)
|
||||
{
|
||||
if (cairo_type1_font_subset_find_segments (font))
|
||||
return font->status;
|
||||
cairo_status_t status;
|
||||
|
||||
if (cairo_type1_font_subset_decrypt_eexec_segment (font))
|
||||
return font->status;
|
||||
status = cairo_type1_font_subset_find_segments (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = cairo_type1_font_subset_decrypt_eexec_segment (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Determine which glyph definition delimiters to use. */
|
||||
if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) {
|
||||
@ -1011,24 +1062,28 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
|
||||
font->nd = "ND";
|
||||
} else {
|
||||
/* Don't know *what* kind of font this is... */
|
||||
return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
|
||||
font->hex_column = 0;
|
||||
|
||||
cairo_type1_font_subset_write_private_dict (font, name);
|
||||
status = cairo_type1_font_subset_write_private_dict (font, name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->base.data_size = _cairo_output_stream_get_position (font->output) -
|
||||
font->base.header_size;
|
||||
|
||||
cairo_type1_font_subset_write_trailer (font);
|
||||
status = cairo_type1_font_subset_write_trailer (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
font->base.trailer_size =
|
||||
_cairo_output_stream_get_position (font->output) -
|
||||
font->base.header_size - font->base.data_size;
|
||||
|
||||
return font->status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1039,45 +1094,52 @@ cairo_type1_font_subset_generate (void *abstract_font,
|
||||
cairo_type1_font_subset_t *font = abstract_font;
|
||||
cairo_ft_unscaled_font_t *ft_unscaled_font;
|
||||
unsigned long ret;
|
||||
cairo_status_t status;
|
||||
|
||||
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
|
||||
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
|
||||
|
||||
/* If anything fails below, it's out of memory. */
|
||||
font->status = CAIRO_STATUS_NO_MEMORY;
|
||||
if (font->face == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font->type1_length = font->face->stream->size;
|
||||
font->type1_data = malloc (font->type1_length);
|
||||
if (font->type1_data == NULL)
|
||||
if (font->type1_data == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (font->face->stream->read) {
|
||||
ret = font->face->stream->read (font->face->stream, 0,
|
||||
(unsigned char *) font->type1_data,
|
||||
font->type1_length);
|
||||
if (ret != font->type1_length)
|
||||
if (ret != font->type1_length) {
|
||||
status = _cairo_error (CAIRO_STATUS_READ_ERROR);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
memcpy (font->type1_data,
|
||||
font->face->stream->base, font->type1_length);
|
||||
}
|
||||
|
||||
if (_cairo_array_grow_by (&font->contents, 4096) != CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_array_grow_by (&font->contents, 4096);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
|
||||
if (font->output == NULL)
|
||||
status = _cairo_output_stream_get_status (font->output);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
font->status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_type1_font_subset_write (font, name);
|
||||
status = cairo_type1_font_subset_write (font, name);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
font->base.data = _cairo_array_index (&font->contents, 0);
|
||||
|
||||
fail:
|
||||
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
|
||||
|
||||
return font->status;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1111,7 +1173,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
|
||||
cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_bool_t hex_encode)
|
||||
{
|
||||
cairo_type1_font_subset_t *font;
|
||||
cairo_type1_font_subset_t *font = NULL; /* hide compiler warning */
|
||||
cairo_status_t status;
|
||||
unsigned long parent_glyph, length;
|
||||
unsigned int i;
|
||||
@ -1203,6 +1265,8 @@ _cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font)
|
||||
PS_FontInfoRec font_info;
|
||||
cairo_bool_t is_type1 = FALSE;
|
||||
|
||||
if (!_cairo_scaled_font_is_ft (scaled_font))
|
||||
return FALSE;
|
||||
unscaled = (cairo_ft_unscaled_font_t *) _cairo_ft_scaled_font_get_unscaled_font (scaled_font);
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
|
||||
@ -54,7 +54,6 @@ typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_
|
||||
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
|
||||
typedef struct _cairo_font_face_backend cairo_font_face_backend_t;
|
||||
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
|
||||
typedef enum _cairo_paginated_mode cairo_paginated_mode_t;
|
||||
typedef cairo_array_t cairo_user_data_array_t;
|
||||
|
||||
/**
|
||||
@ -122,10 +121,10 @@ struct _cairo_cache {
|
||||
int freeze_count;
|
||||
};
|
||||
|
||||
enum _cairo_paginated_mode {
|
||||
typedef enum _cairo_paginated_mode {
|
||||
CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */
|
||||
CAIRO_PAGINATED_MODE_RENDER /* render page contents */
|
||||
};
|
||||
} cairo_paginated_mode_t;
|
||||
|
||||
/* Sure wish C had a real enum type so that this would be distinct
|
||||
from cairo_status_t. Oh well, without that, I'll use this bogus 1000
|
||||
@ -137,7 +136,7 @@ typedef enum _cairo_int_status {
|
||||
CAIRO_INT_STATUS_CACHE_EMPTY,
|
||||
CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
|
||||
CAIRO_INT_STATUS_IMAGE_FALLBACK,
|
||||
CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN,
|
||||
CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN
|
||||
} cairo_int_status_t;
|
||||
|
||||
typedef enum _cairo_internal_surface_type {
|
||||
|
||||
@ -231,18 +231,18 @@ _cairo_utf8_to_ucs4 (const unsigned char *str,
|
||||
{
|
||||
uint32_t wc = _utf8_get_char_extended (in, str + len - in);
|
||||
if (wc & 0x80000000 || !UNICODE_VALID (wc))
|
||||
return CAIRO_STATUS_INVALID_STRING;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_STRING);
|
||||
|
||||
n_chars++;
|
||||
if (n_chars == INT_MAX)
|
||||
return CAIRO_STATUS_INVALID_STRING;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_STRING);
|
||||
|
||||
in = UTF8_NEXT_CHAR (in);
|
||||
}
|
||||
|
||||
str32 = _cairo_malloc_ab (n_chars + 1, sizeof (uint32_t));
|
||||
if (!str32)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
in = str;
|
||||
for (i=0; i < n_chars; i++) {
|
||||
@ -294,7 +294,7 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
||||
while ((len < 0 || str + len - in > 0) && *in) {
|
||||
uint32_t wc = _utf8_get_char_extended (in, str + len - in);
|
||||
if (wc & 0x80000000 || !UNICODE_VALID (wc))
|
||||
return CAIRO_STATUS_INVALID_STRING;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_STRING);
|
||||
|
||||
if (wc < 0x10000)
|
||||
n16 += 1;
|
||||
@ -302,14 +302,14 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
||||
n16 += 2;
|
||||
|
||||
if (n16 == INT_MAX - 1 || n16 == INT_MAX)
|
||||
return CAIRO_STATUS_INVALID_STRING;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_STRING);
|
||||
|
||||
in = UTF8_NEXT_CHAR (in);
|
||||
}
|
||||
|
||||
str16 = _cairo_malloc_ab (n16 + 1, sizeof (uint16_t));
|
||||
if (!str16)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
in = str;
|
||||
for (i = 0; i < n16;) {
|
||||
|
||||
@ -74,6 +74,8 @@
|
||||
#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
|
||||
#endif
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
/*
|
||||
* 64-bit datatypes. Two separate implementations, one using
|
||||
* built-in 64-bit signed/unsigned types another implemented
|
||||
|
||||
@ -234,13 +234,14 @@ _get_system_quality (void)
|
||||
* all be 0, and face_hfont is the result of calling CreateFontIndirectW on
|
||||
* logfont.
|
||||
*/
|
||||
static cairo_scaled_font_t *
|
||||
static cairo_status_t
|
||||
_win32_scaled_font_create (LOGFONTW *logfont,
|
||||
HFONT face_hfont,
|
||||
cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_win32_scaled_font_t *f;
|
||||
cairo_matrix_t scale;
|
||||
@ -248,7 +249,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
||||
|
||||
f = malloc (sizeof(cairo_win32_scaled_font_t));
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
f->logfont = *logfont;
|
||||
|
||||
@ -308,17 +309,17 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
||||
goto FAIL;
|
||||
|
||||
status = _cairo_win32_scaled_font_set_metrics (f);
|
||||
|
||||
if (status) {
|
||||
_cairo_scaled_font_fini (&f->base);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
return &f->base;
|
||||
*font_out = &f->base;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAIL:
|
||||
free (f);
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -413,8 +414,10 @@ _win32_scaled_font_get_unscaled_hfont (cairo_win32_scaled_font_t *scaled_font,
|
||||
}
|
||||
|
||||
otm = malloc (otm_size);
|
||||
if (!otm)
|
||||
if (!otm) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!GetOutlineTextMetrics (hdc, otm_size, otm)) {
|
||||
_cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
|
||||
@ -452,7 +455,7 @@ _cairo_win32_scaled_font_select_unscaled_font (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
hfont = _win32_scaled_font_get_unscaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, hdc);
|
||||
if (!hfont)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
old_hfont = SelectObject (hdc, hfont);
|
||||
if (!old_hfont)
|
||||
@ -484,7 +487,6 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
cairo_scaled_font_t **scaled_font_out)
|
||||
{
|
||||
LOGFONTW logfont;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
uint16_t *face_name;
|
||||
int face_name_len;
|
||||
cairo_status_t status;
|
||||
@ -496,7 +498,7 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
|
||||
if (face_name_len > LF_FACESIZE - 1) {
|
||||
free (face_name);
|
||||
return CAIRO_STATUS_INVALID_STRING;
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_STRING);
|
||||
}
|
||||
|
||||
memcpy (logfont.lfFaceName, face_name, sizeof (uint16_t) * (face_name_len + 1));
|
||||
@ -541,16 +543,11 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
||||
logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
|
||||
if (!logfont.lfFaceName)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
scaled_font = _win32_scaled_font_create (&logfont, NULL, &toy_face->base,
|
||||
font_matrix, ctm, options);
|
||||
if (!scaled_font)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
*scaled_font_out = scaled_font;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return _win32_scaled_font_create (&logfont, NULL, &toy_face->base,
|
||||
font_matrix, ctm, options,
|
||||
scaled_font_out);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -607,13 +604,13 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
||||
|
||||
buffer_size = MAX (n16 * 1.2, 16); /* Initially guess number of chars plus a few */
|
||||
if (buffer_size > INT_MAX) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL1;
|
||||
}
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL1;
|
||||
}
|
||||
|
||||
@ -634,7 +631,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
||||
glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR));
|
||||
dx = _cairo_malloc_ab (buffer_size, sizeof (int));
|
||||
if (!glyph_indices || !dx) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL2;
|
||||
}
|
||||
|
||||
@ -657,7 +654,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
||||
|
||||
buffer_size *= 1.5;
|
||||
if (buffer_size > INT_MAX) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL2;
|
||||
}
|
||||
}
|
||||
@ -665,7 +662,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
||||
*num_glyphs = gcp_results.nGlyphs;
|
||||
*glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t));
|
||||
if (!*glyphs) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL2;
|
||||
}
|
||||
|
||||
@ -706,7 +703,7 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (scaled_font->preserve_axes || scaled_font->base.options.hint_metrics == CAIRO_HINT_METRICS_OFF) {
|
||||
/* For 90-degree rotations (including 0), we get the metrics
|
||||
@ -747,7 +744,7 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
|
||||
|
||||
scaled_font->is_truetype = (metrics.tmPitchAndFamily & TMPF_TRUETYPE) != 0;
|
||||
scaled_font->glyph_indexing = scaled_font->is_truetype ||
|
||||
(GetFontData (hdc, OPENTYPE_CFF_TAG, 0, NULL, 0) != GDI_ERROR);
|
||||
(GetFontData (hdc, OPENTYPE_CFF_TAG, 0, NULL, 0) != GDI_ERROR);
|
||||
// XXX in what situations does this OPENTYPE_CFF thing not have the
|
||||
// TMPF_TRUETYPE flag? GetFontData says it only works on Truetype fonts...
|
||||
|
||||
@ -768,31 +765,31 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (!scaled_font->is_truetype) {
|
||||
/* GetGlyphOutline will not work. Assume that the glyph does not extend outside the font box. */
|
||||
cairo_font_extents_t font_extents;
|
||||
INT width = 0;
|
||||
UINT charIndex = _cairo_scaled_glyph_index (scaled_glyph);
|
||||
/* GetGlyphOutline will not work. Assume that the glyph does not extend outside the font box. */
|
||||
cairo_font_extents_t font_extents;
|
||||
INT width = 0;
|
||||
UINT charIndex = _cairo_scaled_glyph_index (scaled_glyph);
|
||||
|
||||
cairo_scaled_font_extents (&scaled_font->base, &font_extents);
|
||||
cairo_scaled_font_extents (&scaled_font->base, &font_extents);
|
||||
|
||||
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
|
||||
if (!status) {
|
||||
if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
|
||||
width = 0;
|
||||
}
|
||||
}
|
||||
cairo_win32_scaled_font_done_font (&scaled_font->base);
|
||||
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
|
||||
if (!status) {
|
||||
if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
|
||||
width = 0;
|
||||
}
|
||||
}
|
||||
cairo_win32_scaled_font_done_font (&scaled_font->base);
|
||||
|
||||
extents.x_bearing = 0;
|
||||
extents.y_bearing = -font_extents.ascent / scaled_font->y_scale;
|
||||
extents.width = width / scaled_font->x_scale;
|
||||
extents.height = (font_extents.ascent + font_extents.descent) / scaled_font->y_scale;
|
||||
extents.x_advance = extents.width;
|
||||
extents.y_advance = 0;
|
||||
extents.x_bearing = 0;
|
||||
extents.y_bearing = -font_extents.ascent / scaled_font->y_scale;
|
||||
extents.width = width / scaled_font->x_scale;
|
||||
extents.height = (font_extents.ascent + font_extents.descent) / scaled_font->y_scale;
|
||||
extents.x_advance = extents.width;
|
||||
extents.y_advance = 0;
|
||||
} else if (scaled_font->preserve_axes && scaled_font->base.options.hint_style != CAIRO_HINT_METRICS_OFF) {
|
||||
/* If we aren't rotating / skewing the axes, then we get the metrics
|
||||
* from the GDI in device space and convert to font space.
|
||||
@ -886,7 +883,7 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
|
||||
UINT glyph_index_option;
|
||||
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
|
||||
if (status)
|
||||
@ -1034,6 +1031,7 @@ _add_glyph (cairo_glyph_state_t *state,
|
||||
static void
|
||||
_finish_glyphs (cairo_glyph_state_t *state)
|
||||
{
|
||||
/* ignore errors as we only call _finish_glyphs on the error path */
|
||||
_flush_glyphs (state);
|
||||
|
||||
_cairo_array_fini (&state->glyphs);
|
||||
@ -1228,7 +1226,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||
|
||||
tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
|
||||
if (tmp_surface->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return tmp_surface->base.status;
|
||||
|
||||
r.left = 0;
|
||||
r.top = 0;
|
||||
@ -1236,9 +1234,14 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||
r.bottom = height;
|
||||
FillRect (tmp_surface->dc, &r, GetStockObject (WHITE_BRUSH));
|
||||
|
||||
_draw_glyphs_on_surface (tmp_surface, scaled_font, RGB (0, 0, 0),
|
||||
dest_x, dest_y,
|
||||
glyphs, num_glyphs);
|
||||
status = _draw_glyphs_on_surface (tmp_surface,
|
||||
scaled_font, RGB (0, 0, 0),
|
||||
dest_x, dest_y,
|
||||
glyphs, num_glyphs);
|
||||
if (status) {
|
||||
cairo_surface_destroy (&tmp_surface->base);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (scaled_font->quality == CLEARTYPE_QUALITY) {
|
||||
/* For ClearType, we need a 4-channel mask. If we are compositing on
|
||||
@ -1261,7 +1264,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||
mask_surface = _compute_a8_mask (tmp_surface);
|
||||
cairo_surface_destroy (&tmp_surface->base);
|
||||
if (!mask_surface)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* For op == OVER, no-cleartype, a possible optimization here is to
|
||||
@ -1299,7 +1302,7 @@ _cairo_win32_scaled_font_load_truetype_table (void *abstract_font,
|
||||
cairo_win32_scaled_font_t *scaled_font = abstract_font;
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
|
||||
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
|
||||
@ -1335,8 +1338,8 @@ _cairo_win32_transform_FIXED_to_fixed (cairo_matrix_t *matrix,
|
||||
double x = Fx.value + Fx.fract / 65536.0;
|
||||
double y = Fy.value + Fy.fract / 65536.0;
|
||||
cairo_matrix_transform_point (matrix, &x, &y);
|
||||
*fx = _cairo_fixed_from_double (x);
|
||||
*fy = _cairo_fixed_from_double (y);
|
||||
*fx = _cairo_fixed_from_double (x);
|
||||
*fy = _cairo_fixed_from_double (y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1356,11 +1359,11 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
|
||||
hdc = _get_global_font_dc ();
|
||||
if (!hdc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
path = _cairo_path_fixed_create ();
|
||||
if (!path)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE) {
|
||||
status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
|
||||
@ -1390,7 +1393,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
ptr = buffer = malloc (bytesGlyph);
|
||||
|
||||
if (!buffer) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_FONT;
|
||||
}
|
||||
|
||||
@ -1398,8 +1401,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
GGO_NATIVE | glyph_index_option,
|
||||
&metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
|
||||
free (buffer);
|
||||
goto CLEANUP_FONT;
|
||||
goto CLEANUP_BUFFER;
|
||||
}
|
||||
|
||||
while (ptr < buffer + bytesGlyph) {
|
||||
@ -1412,7 +1414,9 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
header->pfxStart.x,
|
||||
header->pfxStart.y,
|
||||
&x, &y);
|
||||
_cairo_path_fixed_move_to (path, x, y);
|
||||
status = _cairo_path_fixed_move_to (path, x, y);
|
||||
if (status)
|
||||
goto CLEANUP_BUFFER;
|
||||
|
||||
while (ptr < endPoly) {
|
||||
TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
|
||||
@ -1425,13 +1429,16 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
points[i].x,
|
||||
points[i].y,
|
||||
&x, &y);
|
||||
_cairo_path_fixed_line_to (path, x, y);
|
||||
status = _cairo_path_fixed_line_to (path, x, y);
|
||||
if (status)
|
||||
goto CLEANUP_BUFFER;
|
||||
}
|
||||
break;
|
||||
case TT_PRIM_QSPLINE:
|
||||
for (i = 0; i < curve->cpfx - 1; i++) {
|
||||
cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
|
||||
_cairo_path_fixed_get_current_point (path, &p1x, &p1y);
|
||||
if (! _cairo_path_fixed_get_current_point (path, &p1x, &p1y))
|
||||
goto CLEANUP_BUFFER;
|
||||
_cairo_win32_transform_FIXED_to_fixed (&transform,
|
||||
points[i].x,
|
||||
points[i].y,
|
||||
@ -1458,7 +1465,9 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
c2x = 2 * cx / 3 + p2x / 3;
|
||||
c2y = 2 * cy / 3 + p2y / 3;
|
||||
|
||||
_cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
|
||||
status = _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
|
||||
if (status)
|
||||
goto CLEANUP_BUFFER;
|
||||
}
|
||||
break;
|
||||
case TT_PRIM_CSPLINE:
|
||||
@ -1476,20 +1485,26 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
|
||||
points[i + 2].x,
|
||||
points[i + 2].y,
|
||||
&x2, &y2);
|
||||
_cairo_path_fixed_curve_to (path, x, y, x1, y1, x2, y2);
|
||||
status = _cairo_path_fixed_curve_to (path, x, y, x1, y1, x2, y2);
|
||||
if (status)
|
||||
goto CLEANUP_BUFFER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);
|
||||
}
|
||||
_cairo_path_fixed_close_path (path);
|
||||
status = _cairo_path_fixed_close_path (path);
|
||||
if (status)
|
||||
goto CLEANUP_BUFFER;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph,
|
||||
&scaled_font->base,
|
||||
path);
|
||||
|
||||
CLEANUP_BUFFER:
|
||||
free (buffer);
|
||||
|
||||
CLEANUP_FONT:
|
||||
cairo_win32_scaled_font_done_font (&scaled_font->base);
|
||||
|
||||
@ -1561,14 +1576,11 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face,
|
||||
}
|
||||
}
|
||||
|
||||
*font = _win32_scaled_font_create (&font_face->logfont,
|
||||
hfont,
|
||||
&font_face->base,
|
||||
font_matrix, ctm, options);
|
||||
if (*font)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
else
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _win32_scaled_font_create (&font_face->logfont,
|
||||
hfont,
|
||||
&font_face->base,
|
||||
font_matrix, ctm, options,
|
||||
font);
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
|
||||
@ -1603,7 +1615,7 @@ cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
|
||||
|
||||
font_face = malloc (sizeof (cairo_win32_font_face_t));
|
||||
if (!font_face) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
@ -1705,7 +1717,7 @@ cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
|
||||
if (!hfont)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
old_hfont = SelectObject (hdc, hfont);
|
||||
if (!old_hfont)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
@ -28,7 +28,7 @@
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* The Initial Developer of the Original Code is Adrian Johnson.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
@ -50,6 +50,7 @@
|
||||
|
||||
#include "cairo-clip-private.h"
|
||||
#include "cairo-win32-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@ -94,11 +95,65 @@ _cairo_win32_printing_surface_init_ps_mode (cairo_win32_surface_t *surface)
|
||||
surface->flags |= CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
analyze_surface_pattern_transparency (cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_int_status_t status;
|
||||
int x, y;
|
||||
|
||||
status = _cairo_surface_acquire_source_image (pattern->surface,
|
||||
&image,
|
||||
&image_extra);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (image->base.status)
|
||||
return image->base.status;
|
||||
|
||||
if (image->format == CAIRO_FORMAT_RGB24) {
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto RELEASE_SOURCE;
|
||||
}
|
||||
|
||||
if (image->format != CAIRO_FORMAT_ARGB32) {
|
||||
/* If the surface does not support the image format, assume
|
||||
* that it does have alpha. The image will be converted to
|
||||
* rgb24 when the surface blends the image into the page
|
||||
* color to remove the transparency. */
|
||||
status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||
goto RELEASE_SOURCE;
|
||||
}
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
int a;
|
||||
uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
|
||||
|
||||
for (x = 0; x < image->width; x++, pixel++) {
|
||||
a = (*pixel & 0xff000000) >> 24;
|
||||
if (a != 255) {
|
||||
status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||
goto RELEASE_SOURCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
RELEASE_SOURCE:
|
||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_extend_t extend;
|
||||
|
||||
if (_cairo_surface_is_meta (pattern->surface))
|
||||
return TRUE;
|
||||
|
||||
if (cairo_surface_get_type (pattern->surface) != CAIRO_SURFACE_TYPE_WIN32 &&
|
||||
pattern->surface->backend->acquire_source_image == NULL)
|
||||
{
|
||||
@ -147,11 +202,10 @@ _cairo_win32_printing_surface_analyze_operation (cairo_win32_surface_t *surface,
|
||||
op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* If IGNORE_OPERATORS was set, then we pretend everything is
|
||||
* OVER/SOURCE. Otherwise, we go to fallback.
|
||||
/* If the operation is anything other than CLEAR, SOURCE, or
|
||||
* OVER, we have to go to fallback.
|
||||
*/
|
||||
if (!(surface->flags & CAIRO_WIN32_SURFACE_IGNORE_OPERATORS) &&
|
||||
op != CAIRO_OPERATOR_OVER)
|
||||
if (op != CAIRO_OPERATOR_OVER)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* CAIRO_OPERATOR_OVER is only supported for opaque patterns. If
|
||||
@ -164,11 +218,14 @@ _cairo_win32_printing_surface_analyze_operation (cairo_win32_surface_t *surface,
|
||||
* background to convert the pattern to opaque.
|
||||
*/
|
||||
|
||||
if (_cairo_operator_always_opaque (op))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
|
||||
|
||||
if (_cairo_operator_always_translucent (op))
|
||||
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||
if ( _cairo_surface_is_meta (surface_pattern->surface))
|
||||
return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
|
||||
else
|
||||
return analyze_surface_pattern_transparency (surface_pattern);
|
||||
}
|
||||
|
||||
if (_cairo_pattern_is_opaque (pattern))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -187,30 +244,56 @@ _cairo_win32_printing_surface_operation_supported (cairo_win32_surface_t *surfac
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_win32_printing_surface_init_clear_color (cairo_win32_surface_t *surface,
|
||||
cairo_solid_pattern_t *color)
|
||||
{
|
||||
if (surface->content == CAIRO_CONTENT_COLOR_ALPHA)
|
||||
_cairo_pattern_init_solid (color, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
|
||||
else
|
||||
_cairo_pattern_init_solid (color, CAIRO_COLOR_BLACK, CAIRO_CONTENT_COLOR);
|
||||
}
|
||||
|
||||
static COLORREF
|
||||
_cairo_win32_printing_surface_flatten_transparency (cairo_win32_surface_t *surface,
|
||||
const cairo_color_t *color)
|
||||
{
|
||||
COLORREF c;
|
||||
BYTE red, green, blue;
|
||||
|
||||
red = color->red_short >> 8;
|
||||
green = color->green_short >> 8;
|
||||
blue = color->blue_short >> 8;
|
||||
|
||||
if (!CAIRO_COLOR_IS_OPAQUE(color)) {
|
||||
if (surface->content == CAIRO_CONTENT_COLOR_ALPHA) {
|
||||
/* Blend into white */
|
||||
uint8_t one_minus_alpha = 255 - (color->alpha_short >> 8);
|
||||
|
||||
red = (color->red_short >> 8) + one_minus_alpha;
|
||||
green = (color->green_short >> 8) + one_minus_alpha;
|
||||
blue = (color->blue_short >> 8) + one_minus_alpha;
|
||||
} else {
|
||||
/* Blend into black */
|
||||
red = (color->red_short >> 8);
|
||||
green = (color->green_short >> 8);
|
||||
blue = (color->blue_short >> 8);
|
||||
}
|
||||
}
|
||||
c = RGB (red, green, blue);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_select_solid_brush (cairo_win32_surface_t *surface,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *) source;
|
||||
cairo_color_t c = pattern->color;
|
||||
COLORREF color;
|
||||
BYTE red, green, blue;
|
||||
|
||||
red = c.red_short >> 8;
|
||||
green = c.green_short >> 8;
|
||||
blue = c.blue_short >> 8;
|
||||
|
||||
if (!CAIRO_COLOR_IS_OPAQUE(&c)) {
|
||||
/* Blend into white */
|
||||
uint8_t one_minus_alpha = 255 - (c.alpha_short >> 8);
|
||||
|
||||
red = (c.red_short >> 8) + one_minus_alpha;
|
||||
green = (c.green_short >> 8) + one_minus_alpha;
|
||||
blue = (c.blue_short >> 8) + one_minus_alpha;
|
||||
}
|
||||
|
||||
color = RGB (red, green, blue);
|
||||
|
||||
color = _cairo_win32_printing_surface_flatten_transparency (surface,
|
||||
&pattern->color);
|
||||
surface->brush = CreateSolidBrush (color);
|
||||
if (!surface->brush)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_select_solid_brush(CreateSolidBrush)");
|
||||
@ -229,6 +312,22 @@ _cairo_win32_printing_surface_done_solid_brush (cairo_win32_surface_t *surface)
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_get_ctm_clip_box (cairo_win32_surface_t *surface,
|
||||
RECT *clip)
|
||||
{
|
||||
XFORM xform;
|
||||
|
||||
_cairo_matrix_to_win32_xform (&surface->ctm, &xform);
|
||||
if (!SetWorldTransform (surface->dc, &xform))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:SetWorldTransform");
|
||||
GetClipBox (surface->dc, clip);
|
||||
if (!ModifyWorldTransform (surface->dc, &xform, MWT_IDENTITY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:ModifyWorldTransform");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_surface_t *surface,
|
||||
cairo_pattern_t *pattern)
|
||||
@ -248,8 +347,135 @@ _cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_surface_t *surfac
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
_cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_content_t old_content;
|
||||
cairo_matrix_t old_ctm;
|
||||
cairo_bool_t old_has_ctm;
|
||||
cairo_rectangle_int_t meta_extents;
|
||||
cairo_status_t status;
|
||||
cairo_extend_t extend;
|
||||
cairo_matrix_t p2d;
|
||||
XFORM xform;
|
||||
int x_tile, y_tile, left, right, top, bottom;
|
||||
RECT clip;
|
||||
cairo_surface_t *meta_surface = pattern->surface;
|
||||
|
||||
extend = cairo_pattern_get_extend (&pattern->base);
|
||||
|
||||
p2d = pattern->base.matrix;
|
||||
status = cairo_matrix_invert (&p2d);
|
||||
/* _cairo_pattern_set_matrix guarantees invertibility */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
old_ctm = surface->ctm;
|
||||
old_has_ctm = surface->has_ctm;
|
||||
cairo_matrix_multiply (&p2d, &p2d, &surface->ctm);
|
||||
surface->ctm = p2d;
|
||||
SaveDC (surface->dc);
|
||||
_cairo_matrix_to_win32_xform (&p2d, &xform);
|
||||
|
||||
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_win32_printing_surface_get_ctm_clip_box (surface, &clip);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
|
||||
left = (int) floor((double)clip.left/meta_extents.width);
|
||||
right = (int) ceil((double)clip.right/meta_extents.width);
|
||||
top = (int) floor((double)clip.top/meta_extents.height);
|
||||
bottom = (int) ceil((double)clip.bottom/meta_extents.height);
|
||||
} else {
|
||||
left = 0;
|
||||
right = 1;
|
||||
top = 0;
|
||||
bottom = 1;
|
||||
}
|
||||
|
||||
old_content = surface->content;
|
||||
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
|
||||
cairo_pattern_t *source;
|
||||
cairo_solid_pattern_t black;
|
||||
|
||||
surface->content = CAIRO_CONTENT_COLOR;
|
||||
_cairo_pattern_init_solid (&black, CAIRO_COLOR_BLACK, CAIRO_CONTENT_COLOR);
|
||||
source = (cairo_pattern_t*) &black;
|
||||
_cairo_win32_printing_surface_paint_solid_pattern (surface, source);
|
||||
}
|
||||
|
||||
for (y_tile = top; y_tile < bottom; y_tile++) {
|
||||
for (x_tile = left; x_tile < right; x_tile++) {
|
||||
cairo_matrix_t m;
|
||||
double x, y;
|
||||
|
||||
SaveDC (surface->dc);
|
||||
m = p2d;
|
||||
cairo_matrix_translate (&m,
|
||||
x_tile*meta_extents.width,
|
||||
y_tile*meta_extents.height);
|
||||
if (extend == CAIRO_EXTEND_REFLECT) {
|
||||
if (x_tile % 2) {
|
||||
cairo_matrix_translate (&m, meta_extents.width, 0);
|
||||
cairo_matrix_scale (&m, -1, 1);
|
||||
}
|
||||
if (y_tile % 2) {
|
||||
cairo_matrix_translate (&m, 0, meta_extents.height);
|
||||
cairo_matrix_scale (&m, 1, -1);
|
||||
}
|
||||
}
|
||||
surface->ctm = m;
|
||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
||||
|
||||
/* Set clip path around bbox of the pattern. */
|
||||
BeginPath (surface->dc);
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
cairo_matrix_transform_point (&surface->ctm, &x, &y);
|
||||
MoveToEx (surface->dc, (int) x, (int) y, NULL);
|
||||
|
||||
x = meta_extents.width;
|
||||
y = 0;
|
||||
cairo_matrix_transform_point (&surface->ctm, &x, &y);
|
||||
LineTo (surface->dc, (int) x, (int) y);
|
||||
|
||||
x = meta_extents.width;
|
||||
y = meta_extents.height;
|
||||
cairo_matrix_transform_point (&surface->ctm, &x, &y);
|
||||
LineTo (surface->dc, (int) x, (int) y);
|
||||
|
||||
x = 0;
|
||||
y = meta_extents.height;
|
||||
cairo_matrix_transform_point (&surface->ctm, &x, &y);
|
||||
LineTo (surface->dc, (int) x, (int) y);
|
||||
|
||||
CloseFigure (surface->dc);
|
||||
EndPath (surface->dc);
|
||||
SelectClipPath (surface->dc, RGN_AND);
|
||||
|
||||
status = _cairo_meta_surface_replay (meta_surface, &surface->base);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
RestoreDC (surface->dc, -1);
|
||||
}
|
||||
}
|
||||
|
||||
surface->content = old_content;
|
||||
surface->ctm = old_ctm;
|
||||
surface->has_ctm = old_has_ctm;
|
||||
RestoreDC (surface->dc, -1);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_extend_t extend;
|
||||
@ -266,13 +492,19 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
XFORM xform;
|
||||
int x_tile, y_tile, left, right, top, bottom;
|
||||
RECT clip;
|
||||
const cairo_color_t *background_color;
|
||||
|
||||
/* If we can't use StretchDIBits with this surface, we can't do anything
|
||||
* special here.
|
||||
* here.
|
||||
*/
|
||||
if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (surface->content == CAIRO_CONTENT_COLOR_ALPHA)
|
||||
background_color = CAIRO_COLOR_WHITE;
|
||||
else
|
||||
background_color = CAIRO_COLOR_BLACK;
|
||||
|
||||
extend = cairo_pattern_get_extend (&pattern->base);
|
||||
status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern,
|
||||
(cairo_surface_t *)surface,
|
||||
@ -290,8 +522,7 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
goto FINISH2;
|
||||
}
|
||||
|
||||
if (image->width == 0 || image->height == 0)
|
||||
{
|
||||
if (image->width == 0 || image->height == 0) {
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto FINISH2;
|
||||
}
|
||||
@ -309,7 +540,7 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
|
||||
status = _cairo_surface_fill_rectangle (opaque_surface,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
CAIRO_COLOR_WHITE,
|
||||
background_color,
|
||||
0, 0,
|
||||
image->width, image->height);
|
||||
if (status) {
|
||||
@ -351,10 +582,12 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
bi.bmiHeader.biClrImportant = 0;
|
||||
|
||||
m = pattern->base.matrix;
|
||||
cairo_matrix_invert (&m);
|
||||
status = cairo_matrix_invert (&m);
|
||||
/* _cairo_pattern_set_matrix guarantees invertibility */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
cairo_matrix_multiply (&m, &m, &surface->ctm);
|
||||
SaveDC (surface->dc);
|
||||
SetGraphicsMode (surface->dc, GM_ADVANCED);
|
||||
_cairo_matrix_to_win32_xform (&m, &xform);
|
||||
|
||||
if (!SetWorldTransform (surface->dc, &xform))
|
||||
@ -390,7 +623,7 @@ _cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *su
|
||||
&bi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_surface_pattern(StretchDIBits)");
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint(StretchDIBits)");
|
||||
}
|
||||
}
|
||||
SetStretchBltMode(surface->dc, oldmode);
|
||||
@ -407,13 +640,29 @@ FINISH:
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
if (_cairo_surface_is_meta (pattern->surface)) {
|
||||
return _cairo_win32_printing_surface_paint_meta_pattern (surface,
|
||||
pattern);
|
||||
} else {
|
||||
return _cairo_win32_printing_surface_paint_image_pattern (surface,
|
||||
pattern);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vertex_set_color (TRIVERTEX *vert, cairo_color_t *color)
|
||||
{
|
||||
vert->Alpha = 0xffff;
|
||||
vert->Red = color->red_short;
|
||||
vert->Green = color->green_short;
|
||||
vert->Blue = color->blue_short;
|
||||
/* MSDN says that the range here is 0x0000 .. 0xff00;
|
||||
* that may well be a typo, but just chop the low bits
|
||||
* here. */
|
||||
vert->Alpha = 0xff00;
|
||||
vert->Red = color->red_short & 0xff00;
|
||||
vert->Green = color->green_short & 0xff00;
|
||||
vert->Blue = color->blue_short & 0xff00;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -430,12 +679,17 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
|
||||
cairo_extend_t extend;
|
||||
int range_start, range_stop, num_ranges, num_rects, stop;
|
||||
int total_verts, total_rects;
|
||||
cairo_status_t status;
|
||||
|
||||
extend = cairo_pattern_get_extend (&pattern->base.base);
|
||||
SaveDC (surface->dc);
|
||||
|
||||
mat = pattern->base.base.matrix;
|
||||
cairo_matrix_invert (&mat);
|
||||
status = cairo_matrix_invert (&mat);
|
||||
/* _cairo_pattern_set_matrix guarantees invertibility */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
cairo_matrix_multiply (&mat, &surface->ctm, &mat);
|
||||
|
||||
p1x = _cairo_fixed_to_double (pattern->p1.x);
|
||||
p1y = _cairo_fixed_to_double (pattern->p1.y);
|
||||
@ -456,16 +710,11 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
|
||||
|
||||
_cairo_matrix_to_win32_xform (&mat, &xform);
|
||||
|
||||
SetGraphicsMode (surface->dc, GM_ADVANCED);
|
||||
if (!SetWorldTransform (surface->dc, &xform))
|
||||
return _cairo_win32_print_gdi_error ("_win32_printing_surface_paint_linear_pattern:SetWorldTransform2");
|
||||
GetWorldTransform(surface->dc, &xform);
|
||||
p1x = 0.0;
|
||||
p1y = 0.0;
|
||||
p2x = d;
|
||||
p2y = 0;
|
||||
|
||||
GetClipBox (surface->dc, &clip);
|
||||
|
||||
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
|
||||
range_start = (int) floor(clip.left/d);
|
||||
range_stop = (int) ceil(clip.right/d);
|
||||
@ -596,9 +845,6 @@ _cairo_win32_printing_surface_paint_pattern (cairo_win32_surface_t *surface,
|
||||
|
||||
typedef struct _win32_print_path_info {
|
||||
cairo_win32_surface_t *surface;
|
||||
cairo_line_cap_t line_cap;
|
||||
cairo_point_t last_move_to_point;
|
||||
cairo_bool_t has_sub_path;
|
||||
} win32_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
@ -606,13 +852,19 @@ _cairo_win32_printing_surface_path_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
win32_path_info_t *path_info = closure;
|
||||
|
||||
path_info->last_move_to_point = *point;
|
||||
path_info->has_sub_path = FALSE;
|
||||
if (path_info->surface->has_ctm) {
|
||||
double x, y;
|
||||
|
||||
MoveToEx (path_info->surface->dc,
|
||||
_cairo_fixed_integer_part (point->x),
|
||||
_cairo_fixed_integer_part (point->y),
|
||||
NULL);
|
||||
x = _cairo_fixed_to_double (point->x);
|
||||
y = _cairo_fixed_to_double (point->y);
|
||||
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
|
||||
MoveToEx (path_info->surface->dc, (int) x, (int) y, NULL);
|
||||
} else {
|
||||
MoveToEx (path_info->surface->dc,
|
||||
_cairo_fixed_integer_part (point->x),
|
||||
_cairo_fixed_integer_part (point->y),
|
||||
NULL);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -622,9 +874,18 @@ _cairo_win32_printing_surface_path_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
win32_path_info_t *path_info = closure;
|
||||
|
||||
LineTo (path_info->surface->dc,
|
||||
_cairo_fixed_integer_part (point->x),
|
||||
_cairo_fixed_integer_part (point->y));
|
||||
if (path_info->surface->has_ctm) {
|
||||
double x, y;
|
||||
|
||||
x = _cairo_fixed_to_double (point->x);
|
||||
y = _cairo_fixed_to_double (point->y);
|
||||
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
|
||||
LineTo (path_info->surface->dc, (int) x, (int) y);
|
||||
} else {
|
||||
LineTo (path_info->surface->dc,
|
||||
_cairo_fixed_integer_part (point->x),
|
||||
_cairo_fixed_integer_part (point->y));
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -638,12 +899,34 @@ _cairo_win32_printing_surface_path_curve_to (void *closure,
|
||||
win32_path_info_t *path_info = closure;
|
||||
POINT points[3];
|
||||
|
||||
points[0].x = _cairo_fixed_integer_part (b->x);
|
||||
points[0].y = _cairo_fixed_integer_part (b->y);
|
||||
points[1].x = _cairo_fixed_integer_part (c->x);
|
||||
points[1].y = _cairo_fixed_integer_part (c->y);
|
||||
points[2].x = _cairo_fixed_integer_part (d->x);
|
||||
points[2].y = _cairo_fixed_integer_part (d->y);
|
||||
if (path_info->surface->has_ctm) {
|
||||
double x, y;
|
||||
|
||||
x = _cairo_fixed_to_double (b->x);
|
||||
y = _cairo_fixed_to_double (b->y);
|
||||
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
|
||||
points[0].x = (LONG) x;
|
||||
points[0].y = (LONG) y;
|
||||
|
||||
x = _cairo_fixed_to_double (c->x);
|
||||
y = _cairo_fixed_to_double (c->y);
|
||||
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
|
||||
points[1].x = (LONG) x;
|
||||
points[1].y = (LONG) y;
|
||||
|
||||
x = _cairo_fixed_to_double (d->x);
|
||||
y = _cairo_fixed_to_double (d->y);
|
||||
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
|
||||
points[2].x = (LONG) x;
|
||||
points[2].y = (LONG) y;
|
||||
} else {
|
||||
points[0].x = _cairo_fixed_integer_part (b->x);
|
||||
points[0].y = _cairo_fixed_integer_part (b->y);
|
||||
points[1].x = _cairo_fixed_integer_part (c->x);
|
||||
points[1].y = _cairo_fixed_integer_part (c->y);
|
||||
points[2].x = _cairo_fixed_integer_part (d->x);
|
||||
points[2].y = _cairo_fixed_integer_part (d->y);
|
||||
}
|
||||
PolyBezierTo (path_info->surface->dc, points, 3);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -749,11 +1032,11 @@ _cairo_win32_printing_surface_paint (void *abstract_surface,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_solid_pattern_t white;
|
||||
cairo_solid_pattern_t clear;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
_cairo_pattern_init_solid (&white, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
|
||||
source = (cairo_pattern_t*) &white;
|
||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||
source = (cairo_pattern_t*) &clear;
|
||||
op = CAIRO_OPERATOR_SOURCE;
|
||||
}
|
||||
|
||||
@ -797,14 +1080,31 @@ _cairo_win32_line_join (cairo_line_join_t join)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
|
||||
{
|
||||
double s;
|
||||
|
||||
s = fabs (m->xx);
|
||||
if (fabs (m->xy) > s)
|
||||
s = fabs (m->xy);
|
||||
if (fabs (m->yx) > s)
|
||||
s = fabs (m->yx);
|
||||
if (fabs (m->yy) > s)
|
||||
s = fabs (m->yy);
|
||||
*scale = s;
|
||||
s = 1.0/s;
|
||||
cairo_matrix_scale (m, s, s);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
cairo_matrix_t *stroke_ctm,
|
||||
cairo_matrix_t *stroke_ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
@ -818,11 +1118,13 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
DWORD *dash_array;
|
||||
HGDIOBJ obj;
|
||||
unsigned int i;
|
||||
cairo_solid_pattern_t white;
|
||||
cairo_solid_pattern_t clear;
|
||||
cairo_matrix_t mat;
|
||||
double scale;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
_cairo_pattern_init_solid (&white, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
|
||||
source = (cairo_pattern_t*) &white;
|
||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||
source = (cairo_pattern_t*) &clear;
|
||||
op = CAIRO_OPERATOR_SOURCE;
|
||||
}
|
||||
|
||||
@ -835,33 +1137,30 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
}
|
||||
|
||||
assert (_cairo_win32_printing_surface_operation_supported (surface, op, source));
|
||||
assert (!(style->num_dashes > 0 && style->dash_offset != 0.0));
|
||||
|
||||
cairo_matrix_multiply (&mat, stroke_ctm, &surface->ctm);
|
||||
_cairo_matrix_factor_out_scale (&mat, &scale);
|
||||
|
||||
pen_style = PS_GEOMETRIC;
|
||||
dash_array = NULL;
|
||||
if (style->num_dashes) {
|
||||
pen_style = PS_USERSTYLE;
|
||||
pen_style |= PS_USERSTYLE;
|
||||
dash_array = calloc (sizeof (DWORD), style->num_dashes);
|
||||
for (i = 0; i < style->num_dashes; i++) {
|
||||
dash_array[i] = (DWORD) style->dash[i];
|
||||
dash_array[i] = (DWORD) (scale * style->dash[i]);
|
||||
}
|
||||
} else {
|
||||
pen_style = PS_SOLID;
|
||||
pen_style |= PS_SOLID;
|
||||
}
|
||||
|
||||
SetMiterLimit (surface->dc, (FLOAT) style->miter_limit, NULL);
|
||||
SetMiterLimit (surface->dc, (FLOAT) (scale * style->miter_limit), NULL);
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
|
||||
cairo_color_t c = solid->color;
|
||||
|
||||
if (!CAIRO_COLOR_IS_OPAQUE(&c)) {
|
||||
/* Blend into white */
|
||||
c.red = c.red*c.alpha + 1 - c.alpha;
|
||||
c.green = c.green*c.alpha + 1 - c.alpha;
|
||||
c.blue = c.blue*c.alpha + 1 - c.alpha;
|
||||
}
|
||||
|
||||
color = RGB ((BYTE)(c.red*255),
|
||||
(BYTE)(c.green*255),
|
||||
(BYTE)(c.blue*255));
|
||||
color = _cairo_win32_printing_surface_flatten_transparency (surface,
|
||||
&solid->color);
|
||||
} else {
|
||||
/* Color not used as the pen will only be used by WidenPath() */
|
||||
color = RGB (0,0,0);
|
||||
@ -869,11 +1168,10 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
brush.lbStyle = BS_SOLID;
|
||||
brush.lbColor = color;
|
||||
brush.lbHatch = 0;
|
||||
pen_style = PS_GEOMETRIC |
|
||||
_cairo_win32_line_cap (style->line_cap) |
|
||||
_cairo_win32_line_join (style->line_join);
|
||||
pen_style |= _cairo_win32_line_cap (style->line_cap);
|
||||
pen_style |= _cairo_win32_line_join (style->line_join);
|
||||
pen = ExtCreatePen(pen_style,
|
||||
style->line_width < 1.0 ? 1 : _cairo_lround(style->line_width),
|
||||
scale * style->line_width,
|
||||
&brush,
|
||||
style->num_dashes,
|
||||
dash_array);
|
||||
@ -893,8 +1191,8 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
* Switch to user space to set line parameters
|
||||
*/
|
||||
SaveDC (surface->dc);
|
||||
SetGraphicsMode (surface->dc, GM_ADVANCED);
|
||||
_cairo_matrix_to_win32_xform (ctm, &xform);
|
||||
|
||||
_cairo_matrix_to_win32_xform (&mat, &xform);
|
||||
xform.eDx = 0.0f;
|
||||
xform.eDy = 0.0f;
|
||||
|
||||
@ -912,7 +1210,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||
/* Return to device space to paint the pattern */
|
||||
if (!ModifyWorldTransform (surface->dc, &xform, MWT_IDENTITY))
|
||||
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ModifyWorldTransform");
|
||||
_cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
}
|
||||
RestoreDC (surface->dc, -1);
|
||||
DeleteObject (pen);
|
||||
@ -933,11 +1231,11 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_int_status_t status;
|
||||
cairo_solid_pattern_t white;
|
||||
cairo_solid_pattern_t clear;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
_cairo_pattern_init_solid (&white, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
|
||||
source = (cairo_pattern_t*) &white;
|
||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||
source = (cairo_pattern_t*) &clear;
|
||||
op = CAIRO_OPERATOR_SOURCE;
|
||||
}
|
||||
|
||||
@ -962,13 +1260,16 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
|
||||
}
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
_cairo_win32_printing_surface_select_solid_brush (surface, source);
|
||||
status = _cairo_win32_printing_surface_select_solid_brush (surface, source);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
FillPath (surface->dc);
|
||||
_cairo_win32_printing_surface_done_solid_brush (surface);
|
||||
} else {
|
||||
SaveDC (surface->dc);
|
||||
SelectClipPath (surface->dc, RGN_AND);
|
||||
_cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
RestoreDC (surface->dc, -1);
|
||||
}
|
||||
|
||||
@ -990,12 +1291,13 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
cairo_pattern_t *opaque = NULL;
|
||||
int i;
|
||||
XFORM xform;
|
||||
cairo_solid_pattern_t white;
|
||||
cairo_matrix_t old_ctm;
|
||||
cairo_bool_t old_has_ctm;
|
||||
cairo_solid_pattern_t clear;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
_cairo_pattern_init_solid (&white, CAIRO_COLOR_WHITE, CAIRO_CONTENT_COLOR);
|
||||
source = (cairo_pattern_t*) &white;
|
||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||
source = (cairo_pattern_t*) &clear;
|
||||
op = CAIRO_OPERATOR_SOURCE;
|
||||
}
|
||||
|
||||
@ -1017,16 +1319,13 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
|
||||
cairo_color_t c = solid->color;
|
||||
COLORREF color;
|
||||
|
||||
if (!CAIRO_COLOR_IS_OPAQUE(&c)) {
|
||||
/* Blend into white */
|
||||
c.red = c.red*c.alpha + 1 - c.alpha;
|
||||
c.green = c.green*c.alpha + 1 - c.alpha;
|
||||
c.blue = c.blue*c.alpha + 1 - c.alpha;
|
||||
}
|
||||
|
||||
opaque = cairo_pattern_create_rgb (c.red, c.green, c.blue);
|
||||
color = _cairo_win32_printing_surface_flatten_transparency (surface,
|
||||
&solid->color);
|
||||
opaque = cairo_pattern_create_rgb (GetRValue (color),
|
||||
GetGValue (color),
|
||||
GetBValue (color));
|
||||
if (opaque->status)
|
||||
return opaque->status;
|
||||
source = opaque;
|
||||
@ -1035,18 +1334,30 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
|
||||
source->type == CAIRO_PATTERN_TYPE_SOLID)
|
||||
{
|
||||
cairo_matrix_t ctm;
|
||||
|
||||
if (surface->has_ctm) {
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
cairo_matrix_transform_point (&surface->ctm, &glyphs[i].x, &glyphs[i].y);
|
||||
cairo_matrix_multiply (&ctm, &scaled_font->ctm, &surface->ctm);
|
||||
scaled_font = cairo_scaled_font_create (scaled_font->font_face,
|
||||
&scaled_font->font_matrix,
|
||||
&ctm,
|
||||
&scaled_font->options);
|
||||
}
|
||||
status = _cairo_win32_surface_show_glyphs (surface, op,
|
||||
source, glyphs,
|
||||
num_glyphs, scaled_font);
|
||||
if (surface->has_ctm)
|
||||
cairo_scaled_font_destroy (scaled_font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SaveDC (surface->dc);
|
||||
SetGraphicsMode (surface->dc, GM_ADVANCED);
|
||||
xform.eM11 = 1.0f;
|
||||
xform.eM21 = 0.0f;
|
||||
xform.eM12 = 0.0f;
|
||||
xform.eM22 = 1.0f;
|
||||
old_ctm = surface->ctm;
|
||||
old_has_ctm = surface->has_ctm;
|
||||
surface->has_ctm = TRUE;
|
||||
BeginPath (surface->dc);
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
@ -1055,16 +1366,16 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
break;
|
||||
xform.eDx = (FLOAT) glyphs[i].x;
|
||||
xform.eDy = (FLOAT) glyphs[i].y;
|
||||
if (!SetWorldTransform (surface->dc, &xform))
|
||||
return _cairo_win32_print_gdi_error ("_win32_surface_print_show_glyphs:SetWorldTransform");
|
||||
surface->ctm = old_ctm;
|
||||
cairo_matrix_translate (&surface->ctm, glyphs[i].x, glyphs[i].y);
|
||||
status = _cairo_win32_printing_surface_emit_path (surface, scaled_glyph->path);
|
||||
}
|
||||
EndPath (surface->dc);
|
||||
if (status == 0) {
|
||||
surface->ctm = old_ctm;
|
||||
surface->has_ctm = old_has_ctm;
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
SelectClipPath (surface->dc, RGN_AND);
|
||||
_cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
|
||||
}
|
||||
RestoreDC (surface->dc, -1);
|
||||
|
||||
@ -1074,12 +1385,33 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_win32_printing_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_printing_surface_start_page (void *abstract_surface)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
XFORM xform;
|
||||
|
||||
SaveDC (surface->dc);
|
||||
SetGraphicsMode (surface->dc, GM_ADVANCED);
|
||||
GetWorldTransform(surface->dc, &xform);
|
||||
surface->ctm.xx = xform.eM11;
|
||||
surface->ctm.xy = xform.eM21;
|
||||
surface->ctm.yx = xform.eM12;
|
||||
surface->ctm.yy = xform.eM22;
|
||||
surface->ctm.x0 = xform.eDx;
|
||||
surface->ctm.y0 = xform.eDy;
|
||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
||||
if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1096,8 +1428,6 @@ _cairo_win32_printing_surface_set_paginated_mode (void *abstract_surface,
|
||||
/**
|
||||
* cairo_win32_printing_surface_create:
|
||||
* @hdc: the DC to create a surface for
|
||||
* @ignore_operators: whether operators other than CLEAR and OVER
|
||||
* should be treated as SOURCE
|
||||
*
|
||||
* Creates a cairo surface that targets the given DC. The DC will be
|
||||
* queried for its initial clip extents, and this will be used as the
|
||||
@ -1106,16 +1436,13 @@ _cairo_win32_printing_surface_set_paginated_mode (void *abstract_surface,
|
||||
* possible to draw to the surface.
|
||||
*
|
||||
* The returned surface will be wrapped using the paginated surface to
|
||||
* provide correct complex renderinf behaviour; show_page() and
|
||||
* provide correct complex rendering behaviour; show_page() and
|
||||
* associated methods must be used for correct output.
|
||||
*
|
||||
* If ignore_operators is TRUE, the rendering may be incorrect;
|
||||
* however, the chances of hitting fallback code are much reduced.
|
||||
*
|
||||
* Return value: the newly created surface
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_win32_printing_surface_create (HDC hdc, cairo_bool_t ignore_operators)
|
||||
cairo_win32_printing_surface_create (HDC hdc)
|
||||
{
|
||||
cairo_win32_surface_t *surface;
|
||||
RECT rect;
|
||||
@ -1126,18 +1453,19 @@ cairo_win32_printing_surface_create (HDC hdc, cairo_bool_t ignore_operators)
|
||||
if (GetClipBox (hdc, &rect) == ERROR) {
|
||||
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
|
||||
/* XXX: Can we make a more reasonable guess at the error cause here? */
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
surface->image = NULL;
|
||||
surface->format = CAIRO_FORMAT_RGB24;
|
||||
surface->content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||
|
||||
surface->dc = hdc;
|
||||
surface->bitmap = NULL;
|
||||
@ -1167,8 +1495,6 @@ cairo_win32_printing_surface_create (HDC hdc, cairo_bool_t ignore_operators)
|
||||
|
||||
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
|
||||
surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
|
||||
if (ignore_operators)
|
||||
surface->flags |= CAIRO_WIN32_SURFACE_IGNORE_OPERATORS;
|
||||
surface->clip_saved_dc = 0;
|
||||
|
||||
_cairo_win32_printing_surface_init_ps_mode (surface);
|
||||
@ -1194,7 +1520,7 @@ _cairo_surface_is_win32_printing (cairo_surface_t *surface)
|
||||
|
||||
static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
|
||||
_cairo_win32_surface_create_similar,
|
||||
_cairo_win32_printing_surface_create_similar,
|
||||
_cairo_win32_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
@ -1224,9 +1550,11 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL, /* fill_stroke */
|
||||
};
|
||||
|
||||
static const cairo_paginated_surface_backend_t cairo_win32_surface_paginated_backend = {
|
||||
_cairo_win32_printing_surface_start_page,
|
||||
_cairo_win32_printing_surface_set_paginated_mode
|
||||
_cairo_win32_printing_surface_set_paginated_mode,
|
||||
NULL, /* set_bounding_box */
|
||||
};
|
||||
|
||||
@ -82,6 +82,9 @@ typedef struct _cairo_win32_surface {
|
||||
|
||||
/* printing surface bits */
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
cairo_content_t content;
|
||||
cairo_bool_t has_ctm;
|
||||
cairo_matrix_t ctm;
|
||||
int clip_saved_dc;
|
||||
HBRUSH brush, old_brush;
|
||||
} cairo_win32_surface_t;
|
||||
@ -108,11 +111,6 @@ enum {
|
||||
|
||||
/* Whether we can use GradientFill rectangles with this surface */
|
||||
CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT = (1<<6),
|
||||
|
||||
/* If we should treat all operators other than CLEAR and OVER
|
||||
* like SOURCE to avoid hitting fallback. Ignored except
|
||||
* for printing. */
|
||||
CAIRO_WIN32_SURFACE_IGNORE_OPERATORS = (1<<7)
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
|
||||
@ -105,7 +105,7 @@ _cairo_win32_print_gdi_error (const char *context)
|
||||
* is no CAIRO_STATUS_UNKNOWN_ERROR.
|
||||
*/
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -151,7 +151,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
char **bits_out,
|
||||
unsigned char **bits_out,
|
||||
int *rowstride_out)
|
||||
{
|
||||
cairo_status_t status;
|
||||
@ -188,7 +188,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
|
||||
if (num_palette > 2) {
|
||||
bitmap_info = _cairo_malloc_ab_plus_c (num_palette, sizeof(RGBQUAD), sizeof(BITMAPINFOHEADER));
|
||||
if (!bitmap_info)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
bitmap_info = (BITMAPINFO *)&bmi_stack;
|
||||
}
|
||||
@ -329,12 +329,12 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_win32_surface_t *surface;
|
||||
char *bits;
|
||||
unsigned char *bits;
|
||||
int rowstride;
|
||||
|
||||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
@ -347,7 +347,7 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
||||
surface->image = cairo_image_surface_create_for_data (bits, format,
|
||||
width, height, rowstride);
|
||||
if (surface->image->status) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
@ -376,13 +376,7 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
||||
if (surface)
|
||||
free (surface);
|
||||
|
||||
if (status == CAIRO_STATUS_NO_MEMORY) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
} else {
|
||||
_cairo_error (status);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
@ -524,7 +518,7 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
||||
(cairo_win32_surface_t *) _cairo_win32_surface_create_similar_internal
|
||||
(surface, content, width, height, TRUE);
|
||||
if (local->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
@ -1431,7 +1425,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* If we are in-memory, then we set the clip on the image surface
|
||||
* as well as on the underlying GDI surface.
|
||||
@ -1440,7 +1434,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
unsigned int serial;
|
||||
|
||||
serial = _cairo_surface_allocate_clip_serial (surface->image);
|
||||
_cairo_surface_set_clip_region (surface->image, region, serial);
|
||||
status = _cairo_surface_set_clip_region (surface->image, region, serial);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* The semantics we want is that any clip set by cairo combines
|
||||
@ -1454,8 +1450,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_box_int_t *boxes;
|
||||
@ -1469,8 +1464,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
/* Create a GDI region for the cairo region */
|
||||
|
||||
_cairo_region_get_extents (region, &extents);
|
||||
if (_cairo_region_get_boxes (region, &num_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (num_boxes == 1 &&
|
||||
boxes[0].p1.x == 0 &&
|
||||
@ -1486,12 +1482,14 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
boxes[0].p1.y,
|
||||
boxes[0].p2.x,
|
||||
boxes[0].p2.y);
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
} else {
|
||||
data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
|
||||
data = malloc (data_size);
|
||||
if (!data) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
rects = (RECT *)data->Buffer;
|
||||
|
||||
@ -1511,35 +1509,31 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
rects[i].bottom = boxes[i].p2.y;
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
|
||||
gdi_region = ExtCreateRegion (NULL, data_size, data);
|
||||
free (data);
|
||||
|
||||
if (!gdi_region)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* Combine the new region with the original clip */
|
||||
if (surface->saved_clip) {
|
||||
if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
|
||||
goto FAIL;
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
||||
}
|
||||
|
||||
if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
||||
goto FAIL;
|
||||
/* Then select the new clip region into our surface if everything went ok */
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
||||
}
|
||||
|
||||
DeleteObject (gdi_region);
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAIL:
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
||||
if (gdi_region)
|
||||
DeleteObject (gdi_region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
@ -1726,7 +1720,7 @@ cairo_win32_surface_create (HDC hdc)
|
||||
if (clipBoxType == ERROR) {
|
||||
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
|
||||
/* XXX: Can we make a more reasonable guess at the error cause here? */
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
@ -1744,7 +1738,7 @@ cairo_win32_surface_create (HDC hdc)
|
||||
format = CAIRO_FORMAT_A1;
|
||||
else {
|
||||
_cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
} else {
|
||||
@ -1753,7 +1747,7 @@ cairo_win32_surface_create (HDC hdc)
|
||||
|
||||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NIL_SURFACE;
|
||||
}
|
||||
|
||||
@ -1859,7 +1853,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
|
||||
ddb_dc = CreateCompatibleDC (hdc);
|
||||
if (ddb_dc == NULL) {
|
||||
_cairo_win32_print_gdi_error("CreateCompatibleDC");
|
||||
new_surf = NIL_SURFACE;
|
||||
new_surf = (cairo_win32_surface_t*) NIL_SURFACE;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
@ -1872,7 +1866,7 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
|
||||
* video memory is probably exhausted.
|
||||
*/
|
||||
_cairo_win32_print_gdi_error("CreateCompatibleBitmap");
|
||||
new_surf = NIL_SURFACE;
|
||||
new_surf = (cairo_win32_surface_t*) NIL_SURFACE;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
@ -48,7 +49,7 @@ cairo_public cairo_surface_t *
|
||||
cairo_win32_surface_create (HDC hdc);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_win32_printing_surface_create (HDC hdc, cairo_bool_t ignore_operators);
|
||||
cairo_win32_printing_surface_create (HDC hdc);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_win32_surface_create_with_ddb (HDC hdc,
|
||||
|
||||
@ -398,7 +398,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
|
||||
}
|
||||
if (!imagerep)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
bpp = _bits_per_pixel(surface->dpy, imagerep->depth);
|
||||
bytes_per_line = _bytes_per_line(surface->dpy, surface->width, bpp);
|
||||
@ -406,7 +406,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
data = _cairo_malloc_ab (surface->height, bytes_per_line);
|
||||
if (data == NULL) {
|
||||
free (imagerep);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
memcpy (data, xcb_get_image_data (imagerep), bytes_per_line * surface->height);
|
||||
@ -479,7 +479,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
|
||||
FAIL:
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -591,7 +591,8 @@ _draw_image_surface (cairo_xcb_surface_t *surface,
|
||||
data_len = height * data_bpl;
|
||||
data_line = data = malloc(data_len);
|
||||
if (data == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
image_line = image->data + src_y * bpl + (src_x * bpp / 8);
|
||||
while (line++ < height) {
|
||||
memcpy(data_line, image_line, data_bpl);
|
||||
@ -720,7 +721,7 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
|
||||
_cairo_xcb_surface_create_similar (surface, content,
|
||||
image_src->width, image_src->height);
|
||||
if (clone->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return clone->base.status;
|
||||
|
||||
_draw_image_surface (clone, image_src, src_x, src_y,
|
||||
width, height, src_x, src_y);
|
||||
@ -1265,8 +1266,8 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||
|
||||
if (num_rects > ARRAY_LENGTH(static_xrects)) {
|
||||
xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
|
||||
if (xrects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (xrects == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
@ -1347,8 +1348,10 @@ _create_trapezoid_mask (cairo_xcb_surface_t *dst,
|
||||
solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
|
||||
|
||||
offset_traps = _cairo_malloc_ab (num_traps, sizeof (xcb_render_trapezoid_t));
|
||||
if (!offset_traps)
|
||||
if (!offset_traps) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return XCB_NONE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = _cairo_fixed_to_16_16(traps[i].top) - 0x10000 * dst_y;
|
||||
@ -1463,7 +1466,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||
dst_x, dst_y, width, height,
|
||||
render_format);
|
||||
if (!mask_picture) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
@ -1495,7 +1498,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
|
||||
xtraps = _cairo_malloc_ab (num_traps, sizeof(xcb_render_trapezoid_t));
|
||||
if (xtraps == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
@ -1555,17 +1558,19 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
XCB_RENDER_CP_CLIP_MASK, none);
|
||||
} else {
|
||||
cairo_box_int_t *boxes;
|
||||
cairo_status_t status;
|
||||
xcb_rectangle_t *rects = NULL;
|
||||
int n_boxes, i;
|
||||
|
||||
if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (n_boxes > 0) {
|
||||
rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
|
||||
if (rects == NULL) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
} else {
|
||||
rects = NULL;
|
||||
@ -1990,7 +1995,7 @@ _cairo_xcb_surface_font_init (xcb_connection_t *dpy,
|
||||
|
||||
font_private = malloc (sizeof (cairo_xcb_surface_font_private_t));
|
||||
if (!font_private)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
font_private->dpy = dpy;
|
||||
font_private->format = format;
|
||||
@ -2108,7 +2113,7 @@ _cairo_xcb_surface_add_glyph (xcb_connection_t *dpy,
|
||||
|
||||
new = malloc (c);
|
||||
if (!new) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
@ -2134,7 +2139,7 @@ _cairo_xcb_surface_add_glyph (xcb_connection_t *dpy,
|
||||
|
||||
new = malloc (c);
|
||||
if (new == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
@ -2375,7 +2380,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||
* 7.1 without EXA). */
|
||||
output_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (output_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (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
|
||||
|
||||
@ -127,13 +127,9 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *display)
|
||||
if (display == NULL)
|
||||
return NULL;
|
||||
|
||||
/* use our mutex until we get a real atomic inc */
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
|
||||
|
||||
assert (display->ref_count > 0);
|
||||
display->ref_count++;
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
_cairo_reference_count_inc (&display->ref_count);
|
||||
|
||||
return display;
|
||||
}
|
||||
@ -144,27 +140,27 @@ _cairo_xlib_display_destroy (cairo_xlib_display_t *display)
|
||||
if (display == NULL)
|
||||
return;
|
||||
|
||||
CAIRO_MUTEX_LOCK (display->mutex);
|
||||
assert (display->ref_count > 0);
|
||||
if (--display->ref_count == 0) {
|
||||
/* destroy all outstanding notifies */
|
||||
while (display->workqueue != NULL) {
|
||||
cairo_xlib_job_t *job = display->workqueue;
|
||||
display->workqueue = job->next;
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&display->ref_count));
|
||||
|
||||
if (job->type == WORK && job->func.work.destroy != NULL)
|
||||
job->func.work.destroy (job->func.work.data);
|
||||
if (! _cairo_reference_count_dec_and_test (&display->ref_count))
|
||||
return;
|
||||
|
||||
_cairo_freelist_free (&display->wq_freelist, job);
|
||||
}
|
||||
_cairo_freelist_fini (&display->wq_freelist);
|
||||
_cairo_freelist_fini (&display->hook_freelist);
|
||||
/* destroy all outstanding notifies */
|
||||
while (display->workqueue != NULL) {
|
||||
cairo_xlib_job_t *job = display->workqueue;
|
||||
display->workqueue = job->next;
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
if (job->type == WORK && job->func.work.destroy != NULL)
|
||||
job->func.work.destroy (job->func.work.data);
|
||||
|
||||
free (display);
|
||||
} else
|
||||
CAIRO_MUTEX_UNLOCK (display->mutex);
|
||||
_cairo_freelist_free (&display->wq_freelist, job);
|
||||
}
|
||||
_cairo_freelist_fini (&display->wq_freelist);
|
||||
_cairo_freelist_fini (&display->hook_freelist);
|
||||
|
||||
CAIRO_MUTEX_FINI (display->mutex);
|
||||
|
||||
free (display);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -177,6 +173,29 @@ static int
|
||||
_cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
|
||||
{
|
||||
cairo_xlib_display_t *display, **prev, *next;
|
||||
cairo_xlib_error_func_t old_handler;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);
|
||||
for (display = _cairo_xlib_display_list; display; display = display->next)
|
||||
if (display->display == dpy)
|
||||
break;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
|
||||
if (display == NULL)
|
||||
return 0;
|
||||
|
||||
/* protect the notifies from triggering XErrors */
|
||||
XSync (dpy, False);
|
||||
old_handler = XSetErrorHandler (_noop_error_handler);
|
||||
|
||||
_cairo_xlib_display_notify (display);
|
||||
_cairo_xlib_call_close_display_hooks (display);
|
||||
_cairo_xlib_display_discard_screens (display);
|
||||
|
||||
/* catch any that arrived before marking the display as closed */
|
||||
_cairo_xlib_display_notify (display);
|
||||
|
||||
XSync (dpy, False);
|
||||
XSetErrorHandler (old_handler);
|
||||
|
||||
/*
|
||||
* Unhook from the global list
|
||||
@ -186,27 +205,6 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
|
||||
for (display = _cairo_xlib_display_list; display; display = next) {
|
||||
next = display->next;
|
||||
if (display->display == dpy) {
|
||||
cairo_xlib_error_func_t old_handler;
|
||||
|
||||
/* drop the list mutex whilst triggering the hooks */
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
|
||||
|
||||
/* protect the notifies from triggering XErrors */
|
||||
XSync (dpy, False);
|
||||
old_handler = XSetErrorHandler (_noop_error_handler);
|
||||
|
||||
_cairo_xlib_display_notify (display);
|
||||
_cairo_xlib_call_close_display_hooks (display);
|
||||
_cairo_xlib_display_discard_screens (display);
|
||||
|
||||
/* catch any that arrived before marking the display as closed */
|
||||
_cairo_xlib_display_notify (display);
|
||||
|
||||
XSync (dpy, False);
|
||||
XSetErrorHandler (old_handler);
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);
|
||||
_cairo_xlib_display_destroy (display);
|
||||
*prev = next;
|
||||
break;
|
||||
} else
|
||||
@ -214,6 +212,8 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
|
||||
}
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
|
||||
|
||||
_cairo_xlib_display_destroy (display);
|
||||
|
||||
/* Return value in accordance with requirements of
|
||||
* XESetCloseDisplay */
|
||||
return 0;
|
||||
@ -257,8 +257,10 @@ _cairo_xlib_display_get (Display *dpy)
|
||||
}
|
||||
|
||||
display = malloc (sizeof (cairo_xlib_display_t));
|
||||
if (display == NULL)
|
||||
if (display == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
goto UNLOCK;
|
||||
}
|
||||
|
||||
/* Xlib calls out to the extension close_display hooks in LIFO
|
||||
* order. So we have to ensure that all extensions that we depend
|
||||
@ -280,7 +282,7 @@ _cairo_xlib_display_get (Display *dpy)
|
||||
_cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
|
||||
_cairo_freelist_init (&display->hook_freelist, sizeof (cairo_xlib_hook_t));
|
||||
|
||||
display->ref_count = 2; /* add one for the CloseDisplay */
|
||||
CAIRO_REFERENCE_COUNT_INIT (&display->ref_count, 2); /* add one for the CloseDisplay */
|
||||
CAIRO_MUTEX_INIT (display->mutex);
|
||||
display->display = dpy;
|
||||
display->screens = NULL;
|
||||
@ -288,6 +290,15 @@ _cairo_xlib_display_get (Display *dpy)
|
||||
display->close_display_hooks = NULL;
|
||||
display->closed = FALSE;
|
||||
|
||||
display->buggy_repeat = FALSE;
|
||||
if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
|
||||
if (VendorRelease (dpy) <= 60802000)
|
||||
display->buggy_repeat = TRUE;
|
||||
} else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
|
||||
if (VendorRelease (dpy) <= 40500000)
|
||||
display->buggy_repeat = TRUE;
|
||||
}
|
||||
|
||||
display->next = _cairo_xlib_display_list;
|
||||
_cairo_xlib_display_list = display;
|
||||
|
||||
|
||||
@ -34,9 +34,13 @@
|
||||
#define CAIRO_XLIB_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-xlib.h"
|
||||
#include "cairo-xlib-xrender-private.h"
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-freelist-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-xlib-xrender-private.h"
|
||||
|
||||
#include <X11/Xutil.h> /* for XDestroyImage */
|
||||
|
||||
@ -55,7 +59,7 @@ struct _cairo_xlib_hook {
|
||||
|
||||
struct _cairo_xlib_display {
|
||||
cairo_xlib_display_t *next;
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_mutex_t mutex;
|
||||
|
||||
Display *display;
|
||||
@ -66,12 +70,13 @@ struct _cairo_xlib_display {
|
||||
|
||||
cairo_freelist_t hook_freelist;
|
||||
cairo_xlib_hook_t *close_display_hooks;
|
||||
unsigned int buggy_repeat :1;
|
||||
unsigned int closed :1;
|
||||
};
|
||||
|
||||
struct _cairo_xlib_screen_info {
|
||||
cairo_xlib_screen_info_t *next;
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
|
||||
cairo_xlib_display_t *display;
|
||||
Screen *screen;
|
||||
|
||||
@ -246,8 +246,9 @@ _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
|
||||
if (info == NULL)
|
||||
return NULL;
|
||||
|
||||
assert (info->ref_count > 0);
|
||||
info->ref_count++;
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&info->ref_count);
|
||||
|
||||
return info;
|
||||
}
|
||||
@ -274,8 +275,9 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
assert (info->ref_count > 0);
|
||||
if (--info->ref_count)
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&info->ref_count))
|
||||
return;
|
||||
|
||||
CAIRO_MUTEX_LOCK (info->display->mutex);
|
||||
@ -330,7 +332,7 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
|
||||
} else {
|
||||
info = malloc (sizeof (cairo_xlib_screen_info_t));
|
||||
if (info != NULL) {
|
||||
info->ref_count = 2; /* Add one for display cache */
|
||||
CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
|
||||
info->display = _cairo_xlib_display_reference (display);
|
||||
info->screen = screen;
|
||||
info->has_render = FALSE;
|
||||
|
||||
@ -172,7 +172,7 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
|
||||
width, height);
|
||||
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
|
||||
XFreePixmap (dpy, pix);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -192,10 +192,10 @@ _xrender_format_to_content (XRenderPictFormat *xrender_format)
|
||||
if (xrender_format == NULL)
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
|
||||
xrender_format_has_alpha = (xrender_format->direct.alpha != 0);
|
||||
xrender_format_has_color = (xrender_format->direct.red != 0 ||
|
||||
xrender_format->direct.green != 0 ||
|
||||
xrender_format->direct.blue != 0);
|
||||
xrender_format_has_alpha = (xrender_format->direct.alphaMask != 0);
|
||||
xrender_format_has_color = (xrender_format->direct.redMask != 0 ||
|
||||
xrender_format->direct.greenMask != 0 ||
|
||||
xrender_format->direct.blueMask != 0);
|
||||
|
||||
if (xrender_format_has_alpha)
|
||||
if (xrender_format_has_color)
|
||||
@ -252,7 +252,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
|
||||
width, height);
|
||||
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
|
||||
XFreePixmap (src->dpy, pix);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
}
|
||||
}
|
||||
if (!ximage)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_swap_ximage_to_native (ximage);
|
||||
|
||||
@ -615,7 +615,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
|
||||
FAIL:
|
||||
XDestroyImage (ximage);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -694,7 +694,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
|
||||
surface->gc = XCreateGC (surface->dpy, surface->drawable,
|
||||
GCGraphicsExposures, &gcv);
|
||||
if (!surface->gc)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
_cairo_xlib_surface_set_gc_clip_rects (surface);
|
||||
@ -810,10 +810,12 @@ _cairo_xlib_surface_release_dest_image (void *abstract_surfac
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
/* ignore errors */
|
||||
_draw_image_surface (surface, image, 0, 0, image->width, image->height,
|
||||
image_rect->x, image_rect->y);
|
||||
status = _draw_image_surface (surface, image,
|
||||
0, 0, image->width, image->height,
|
||||
image_rect->x, image_rect->y);
|
||||
status = _cairo_surface_set_error (&surface->base, status);
|
||||
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
@ -863,7 +865,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
|
||||
_cairo_xlib_surface_create_similar_with_format (surface, image_src->format,
|
||||
image_src->width, image_src->height);
|
||||
if (clone->base.status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return clone->base.status;
|
||||
|
||||
status = _draw_image_surface (clone, image_src, src_x, src_y,
|
||||
width, height, src_x, src_y);
|
||||
@ -1196,10 +1198,8 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst,
|
||||
return DO_XCOPYAREA;
|
||||
}
|
||||
|
||||
if (!dst->buggy_repeat)
|
||||
return DO_RENDER;
|
||||
|
||||
if (is_integer_translation &&
|
||||
if (dst->buggy_repeat &&
|
||||
is_integer_translation &&
|
||||
src_attr->extend == CAIRO_EXTEND_REPEAT &&
|
||||
(src->width != 1 || src->height != 1))
|
||||
{
|
||||
@ -1213,6 +1213,9 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst,
|
||||
return DO_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src))
|
||||
return DO_UNSUPPORTED;
|
||||
|
||||
return DO_RENDER;
|
||||
}
|
||||
|
||||
@ -1317,13 +1320,13 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
status = _cairo_xlib_surface_set_attributes (src, &src_attr);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case DO_RENDER:
|
||||
status = _cairo_xlib_surface_set_attributes (src, &src_attr);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
_cairo_xlib_surface_ensure_dst_picture (dst);
|
||||
if (mask) {
|
||||
status = _cairo_xlib_surface_set_attributes (mask, &mask_attr);
|
||||
@ -1445,8 +1448,8 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface,
|
||||
|
||||
if (num_rects > ARRAY_LENGTH(static_xrects)) {
|
||||
xrects = _cairo_malloc_ab (num_rects, sizeof(XRectangle));
|
||||
if (xrects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (xrects == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
@ -1534,6 +1537,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
|
||||
offset_traps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
|
||||
if (!offset_traps) {
|
||||
XRenderFreePicture (dst->dpy, mask_picture);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -1651,7 +1655,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
||||
dst_x, dst_y, width, height,
|
||||
pict_format);
|
||||
if (!mask_picture) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
@ -1683,7 +1687,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
|
||||
xtraps = _cairo_malloc_ab (num_traps, sizeof(XTrapezoid));
|
||||
if (xtraps == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
@ -1738,17 +1742,19 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
|
||||
|
||||
if (region != NULL) {
|
||||
cairo_box_int_t *boxes;
|
||||
cairo_status_t status;
|
||||
XRectangle *rects = NULL;
|
||||
int n_boxes, i;
|
||||
|
||||
if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
|
||||
rects = _cairo_malloc_ab (n_boxes, sizeof(XRectangle));
|
||||
if (rects == NULL) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
} else {
|
||||
rects = surface->embedded_clip_rects;
|
||||
@ -1937,14 +1943,14 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
|
||||
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
|
||||
if (screen_info == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = malloc (sizeof (cairo_xlib_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_xlib_screen_info_destroy (screen_info);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -1952,7 +1958,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
_cairo_xlib_surface_detach_display, surface, surface)) {
|
||||
free (surface);
|
||||
_cairo_xlib_screen_info_destroy (screen_info);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -2007,14 +2013,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->buggy_repeat = FALSE;
|
||||
if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
|
||||
if (VendorRelease (dpy) <= 60802000)
|
||||
surface->buggy_repeat = TRUE;
|
||||
} else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
|
||||
if (VendorRelease (dpy) <= 40500000)
|
||||
surface->buggy_repeat = TRUE;
|
||||
}
|
||||
surface->buggy_repeat = screen_info->display->buggy_repeat;
|
||||
|
||||
surface->dst_picture = None;
|
||||
surface->src_picture = None;
|
||||
@ -2091,10 +2090,12 @@ cairo_xlib_surface_create (Display *dpy,
|
||||
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
|
||||
|
||||
if (screen == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_VISUAL);
|
||||
_cairo_error_throw (CAIRO_STATUS_INVALID_VISUAL);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
|
||||
visual, NULL, width, height, 0);
|
||||
}
|
||||
@ -2119,6 +2120,8 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
return _cairo_xlib_surface_create_internal (dpy, bitmap, screen,
|
||||
NULL, NULL, width, height, 1);
|
||||
}
|
||||
@ -2152,6 +2155,8 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
|
||||
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
|
||||
NULL, format, width, height, 0);
|
||||
}
|
||||
@ -2180,10 +2185,11 @@ cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
|
||||
int height)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_surface_set_error (abstract_surface,
|
||||
CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
status = _cairo_surface_set_error (abstract_surface,
|
||||
CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2214,7 +2220,8 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
|
||||
cairo_status_t status;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_surface_set_error (abstract_surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
status = _cairo_surface_set_error (abstract_surface,
|
||||
CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2229,7 +2236,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
|
||||
XRenderFreePicture,
|
||||
surface->dst_picture);
|
||||
if (status) {
|
||||
_cairo_surface_set_error (&surface->base, status);
|
||||
status = _cairo_surface_set_error (&surface->base, status);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2242,7 +2249,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
|
||||
XRenderFreePicture,
|
||||
surface->src_picture);
|
||||
if (status) {
|
||||
_cairo_surface_set_error (&surface->base, status);
|
||||
status = _cairo_surface_set_error (&surface->base, status);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2271,7 +2278,7 @@ cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2294,7 +2301,7 @@ cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2317,7 +2324,7 @@ cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2340,7 +2347,7 @@ cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2363,7 +2370,7 @@ cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2386,7 +2393,7 @@ cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2409,7 +2416,7 @@ cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2452,13 +2459,13 @@ _cairo_xlib_surface_font_init (Display *dpy,
|
||||
|
||||
font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
|
||||
if (!font_private)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (!_cairo_xlib_add_close_display_hook (dpy,
|
||||
_cairo_xlib_surface_remove_scaled_font,
|
||||
scaled_font, scaled_font)) {
|
||||
free (font_private);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
@ -2546,15 +2553,34 @@ _native_byte_order_lsb (void)
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph)
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_scaled_glyph_t **pscaled_glyph)
|
||||
{
|
||||
XGlyphInfo glyph_info;
|
||||
unsigned long glyph_index;
|
||||
unsigned char *data;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_xlib_surface_font_private_t *font_private;
|
||||
cairo_scaled_glyph_t *scaled_glyph = *pscaled_glyph;
|
||||
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
|
||||
cairo_bool_t already_had_glyph_surface;
|
||||
|
||||
if (!glyph_surface) {
|
||||
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
_cairo_scaled_glyph_index (scaled_glyph),
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS |
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
pscaled_glyph);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
scaled_glyph = *pscaled_glyph;
|
||||
glyph_surface = scaled_glyph->surface;
|
||||
already_had_glyph_surface = FALSE;
|
||||
} else {
|
||||
already_had_glyph_surface = TRUE;
|
||||
}
|
||||
|
||||
if (scaled_font->surface_private == NULL) {
|
||||
status = _cairo_xlib_surface_font_init (dpy, scaled_font,
|
||||
@ -2564,22 +2590,16 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
}
|
||||
font_private = scaled_font->surface_private;
|
||||
|
||||
/* If the glyph format does not match the font format, then we
|
||||
* create a temporary surface for the glyph image with the font's
|
||||
* format.
|
||||
/* If the glyph surface has zero height or width, we create
|
||||
* a clear 1x1 surface, to avoid various X server bugs.
|
||||
*/
|
||||
if (glyph_surface->format != font_private->format) {
|
||||
if ((glyph_surface->width == 0) || (glyph_surface->height == 0)) {
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *tmp_surface;
|
||||
double x_offset, y_offset;
|
||||
|
||||
tmp_surface = cairo_image_surface_create (font_private->format,
|
||||
glyph_surface->width,
|
||||
glyph_surface->height);
|
||||
tmp_surface = cairo_image_surface_create (font_private->format, 1, 1);
|
||||
cr = cairo_create (tmp_surface);
|
||||
cairo_surface_get_device_offset (&glyph_surface->base, &x_offset, &y_offset);
|
||||
cairo_set_source_surface (cr, &glyph_surface->base, x_offset, y_offset);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint (cr);
|
||||
|
||||
status = cairo_status (cr);
|
||||
@ -2595,6 +2615,36 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* If the glyph format does not match the font format, then we
|
||||
* create a temporary surface for the glyph image with the font's
|
||||
* format.
|
||||
*/
|
||||
if (glyph_surface->format != font_private->format) {
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *tmp_surface;
|
||||
|
||||
tmp_surface = cairo_image_surface_create (font_private->format,
|
||||
glyph_surface->width,
|
||||
glyph_surface->height);
|
||||
tmp_surface->device_transform = glyph_surface->base.device_transform;
|
||||
tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
|
||||
|
||||
cr = cairo_create (tmp_surface);
|
||||
|
||||
cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
|
||||
status = cairo_status (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
glyph_surface = (cairo_image_surface_t *) tmp_surface;
|
||||
|
||||
if (status)
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */
|
||||
glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0);
|
||||
glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0);
|
||||
@ -2616,7 +2666,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
|
||||
new = malloc (c);
|
||||
if (!new) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
@ -2642,7 +2692,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
|
||||
new = malloc (c);
|
||||
if (new == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
@ -2681,6 +2731,15 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
if (glyph_surface != scaled_glyph->surface)
|
||||
cairo_surface_destroy (&glyph_surface->base);
|
||||
|
||||
/* if the scaled glyph didn't already have a surface attached
|
||||
* to it, release the created surface now that we have it
|
||||
* uploaded to the X server. If the surface has already been
|
||||
* there (eg. because image backend requested it), leave it in
|
||||
* the cache
|
||||
*/
|
||||
if (!already_had_glyph_surface)
|
||||
_cairo_scaled_glyph_set_surface (scaled_glyph, scaled_font, NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -2770,7 +2829,7 @@ _cairo_xlib_surface_emit_glyphs_chunk (cairo_xlib_surface_t *dst,
|
||||
} else {
|
||||
elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8));
|
||||
if (elts == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Fill them in */
|
||||
@ -2866,7 +2925,6 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
|
||||
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE |
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
@ -2877,14 +2935,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
|
||||
|
||||
/* Glyph skipping:
|
||||
*
|
||||
* We skip any initial size-zero glyphs to avoid an X server bug (present
|
||||
* in at least Xorg 7.1 without EXA) which stops rendering glyphs after
|
||||
* the first zero-size glyph. However, we don't skip all size-zero
|
||||
* glyphs, since that will force a new element at every space. We
|
||||
* skip initial size-zero glyphs and hope that it's enough. Since
|
||||
* Xft never exposed that bug, this assumption should be correct.
|
||||
*
|
||||
* We also skip any glyphs that have troublesome coordinates. We want
|
||||
* We skip any glyphs that have troublesome coordinates. We want
|
||||
* to make sure that (glyph2.x - (glyph1.x + glyph1.width)) fits in
|
||||
* a signed 16bit integer, otherwise it will overflow in the render
|
||||
* protocol.
|
||||
@ -2898,8 +2949,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
|
||||
* Anyway, we will allow positions in the range -1024..15359. That
|
||||
* will buy us a few more years before this stops working.
|
||||
*/
|
||||
if ((!num_out_glyphs && !(scaled_glyph->surface->width && scaled_glyph->surface->height)) ||
|
||||
(((this_x+1024)|(this_y+1024))&~0x3fffu)) {
|
||||
if (((this_x+1024)|(this_y+1024))&~0x3fffu) {
|
||||
glyphs[i].index = GLYPH_INDEX_SKIP;
|
||||
continue;
|
||||
}
|
||||
@ -2955,7 +3005,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst,
|
||||
if (scaled_glyph->surface_private == NULL) {
|
||||
status = _cairo_xlib_surface_add_glyph (dst->dpy,
|
||||
scaled_font,
|
||||
scaled_glyph);
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
return status;
|
||||
scaled_glyph->surface_private = (void *) 1;
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
#define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */
|
||||
|
||||
static const cairo_t _cairo_nil = {
|
||||
CAIRO_REF_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
{ 0, 0, 0, NULL }, /* user_data */
|
||||
NULL, /* gstate */
|
||||
@ -53,11 +53,11 @@ static const cairo_t _cairo_nil = {
|
||||
0
|
||||
}},
|
||||
{{ /* path */
|
||||
{ 0, 0 }, /* last_move_point */
|
||||
{ 0, 0 }, /* current point */
|
||||
FALSE, /* has_current_point */
|
||||
FALSE, /* has_curve_to */
|
||||
NULL, {{0}} /* buf_tail, buf_head */
|
||||
{ 0, 0 }, /* last_move_point */
|
||||
{ 0, 0 }, /* current point */
|
||||
FALSE, /* has_current_point */
|
||||
FALSE, /* has_curve_to */
|
||||
NULL, {{NULL}} /* buf_tail, buf_head */
|
||||
}}
|
||||
};
|
||||
|
||||
@ -83,12 +83,16 @@ static const cairo_t _cairo_nil = {
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
*
|
||||
* Return value: the error status.
|
||||
**/
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_error (cairo_status_t status)
|
||||
{
|
||||
assert (status > CAIRO_STATUS_SUCCESS &&
|
||||
status <= CAIRO_STATUS_LAST_STATUS);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,11 +101,11 @@ _cairo_error (cairo_status_t status)
|
||||
* @status: a status value indicating an error, (eg. not
|
||||
* CAIRO_STATUS_SUCCESS)
|
||||
*
|
||||
* Sets cr->status to @status and calls _cairo_error;
|
||||
* Atomically sets cr->status to @status and calls _cairo_error;
|
||||
*
|
||||
* All assignments of an error status to cr->status should happen
|
||||
* through _cairo_set_error() or else _cairo_error() should be
|
||||
* called immediately after the assignment.
|
||||
* through _cairo_set_error(). Note that due to the nature of the atomic
|
||||
* operation, it is not safe to call this function on the nil objects.
|
||||
*
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
@ -111,12 +115,10 @@ static void
|
||||
_cairo_set_error (cairo_t *cr, cairo_status_t status)
|
||||
{
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. It also avoids attempting
|
||||
* to write to read-only data (eg. from a nil cairo_t). */
|
||||
if (cr->status == CAIRO_STATUS_SUCCESS)
|
||||
cr->status = status;
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&cr->status, status);
|
||||
|
||||
_cairo_error (status);
|
||||
status = _cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,10 +198,12 @@ cairo_create (cairo_surface_t *target)
|
||||
return (cairo_t *) &_cairo_nil;
|
||||
|
||||
cr = malloc (sizeof (cairo_t));
|
||||
if (cr == NULL)
|
||||
if (cr == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_t *) &_cairo_nil;
|
||||
}
|
||||
|
||||
cr->ref_count = 1;
|
||||
CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1);
|
||||
|
||||
cr->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
@ -232,12 +236,12 @@ slim_hidden_def (cairo_create);
|
||||
cairo_t *
|
||||
cairo_reference (cairo_t *cr)
|
||||
{
|
||||
if (cr == NULL || cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
|
||||
return cr;
|
||||
|
||||
assert (cr->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count));
|
||||
|
||||
cr->ref_count++;
|
||||
_cairo_reference_count_inc (&cr->ref_count);
|
||||
|
||||
return cr;
|
||||
}
|
||||
@ -253,13 +257,12 @@ cairo_reference (cairo_t *cr)
|
||||
void
|
||||
cairo_destroy (cairo_t *cr)
|
||||
{
|
||||
if (cr == NULL || cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
|
||||
return;
|
||||
|
||||
assert (cr->ref_count > 0);
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count));
|
||||
|
||||
cr->ref_count--;
|
||||
if (cr->ref_count)
|
||||
if (! _cairo_reference_count_dec_and_test (&cr->ref_count))
|
||||
return;
|
||||
|
||||
while (cr->gstate != cr->gstate_tail) {
|
||||
@ -323,8 +326,8 @@ cairo_set_user_data (cairo_t *cr,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return _cairo_user_data_array_set_data (&cr->user_data,
|
||||
key, user_data, destroy);
|
||||
@ -344,10 +347,10 @@ cairo_set_user_data (cairo_t *cr,
|
||||
unsigned int
|
||||
cairo_get_reference_count (cairo_t *cr)
|
||||
{
|
||||
if (cr == NULL || cr->ref_count == CAIRO_REF_COUNT_INVALID)
|
||||
if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
|
||||
return 0;
|
||||
|
||||
return cr->ref_count;
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&cr->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,6 +1073,9 @@ cairo_get_dash_count (cairo_t *cr)
|
||||
{
|
||||
int num_dashes;
|
||||
|
||||
if (cr->status)
|
||||
return 0;
|
||||
|
||||
_cairo_gstate_get_dash (cr->gstate, NULL, &num_dashes, NULL);
|
||||
|
||||
return num_dashes;
|
||||
@ -1092,6 +1098,9 @@ cairo_get_dash (cairo_t *cr,
|
||||
double *dashes,
|
||||
double *offset)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
_cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset);
|
||||
}
|
||||
|
||||
@ -1519,7 +1528,8 @@ slim_hidden_def (cairo_curve_to);
|
||||
*
|
||||
* If there is a current point, an initial line segment will be added
|
||||
* to the path to connect the current point to the beginning of the
|
||||
* arc.
|
||||
* arc. If this initial line is undesired, it can be avoided by
|
||||
* calling cairo_new_sub_path() before calling cairo_arc().
|
||||
*
|
||||
* Angles are measured in radians. An angle of 0.0 is in the direction
|
||||
* of the positive X axis (in user space). An angle of %M_PI/2.0 radians
|
||||
@ -2415,8 +2425,11 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
if (list == NULL)
|
||||
if (list == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
list->status = status;
|
||||
list->rectangles = NULL;
|
||||
list->num_rectangles = 0;
|
||||
@ -2625,6 +2638,11 @@ cairo_set_font_matrix (cairo_t *cr,
|
||||
void
|
||||
cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix)
|
||||
{
|
||||
if (cr->status) {
|
||||
cairo_matrix_init_identity (matrix);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_gstate_get_font_matrix (cr->gstate, matrix);
|
||||
}
|
||||
|
||||
@ -2676,6 +2694,11 @@ cairo_get_font_options (cairo_t *cr,
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
if (cr->status) {
|
||||
_cairo_font_options_init_default (options);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_gstate_get_font_options (cr->gstate, options);
|
||||
}
|
||||
|
||||
@ -3071,6 +3094,9 @@ cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
|
||||
cairo_operator_t
|
||||
cairo_get_operator (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_operator_t) 0;
|
||||
|
||||
return _cairo_gstate_get_operator (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3085,6 +3111,9 @@ cairo_get_operator (cairo_t *cr)
|
||||
double
|
||||
cairo_get_tolerance (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return 0.;
|
||||
|
||||
return _cairo_gstate_get_tolerance (cr->gstate);
|
||||
}
|
||||
slim_hidden_def (cairo_get_tolerance);
|
||||
@ -3100,6 +3129,9 @@ slim_hidden_def (cairo_get_tolerance);
|
||||
cairo_antialias_t
|
||||
cairo_get_antialias (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_antialias_t) 0;
|
||||
|
||||
return _cairo_gstate_get_antialias (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3135,19 +3167,21 @@ cairo_get_antialias (cairo_t *cr)
|
||||
void
|
||||
cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_fixed_t x_fixed, y_fixed;
|
||||
double x, y;
|
||||
|
||||
status = _cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed);
|
||||
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
|
||||
x = 0.0;
|
||||
y = 0.0;
|
||||
} else {
|
||||
if (cr->status == CAIRO_STATUS_SUCCESS &&
|
||||
_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
|
||||
{
|
||||
x = _cairo_fixed_to_double (x_fixed);
|
||||
y = _cairo_fixed_to_double (y_fixed);
|
||||
_cairo_gstate_backend_to_user (cr->gstate, &x, &y);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 0.0;
|
||||
y = 0.0;
|
||||
}
|
||||
|
||||
if (x_ret)
|
||||
*x_ret = x;
|
||||
@ -3167,6 +3201,9 @@ slim_hidden_def(cairo_get_current_point);
|
||||
cairo_fill_rule_t
|
||||
cairo_get_fill_rule (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_fill_rule_t) 0;
|
||||
|
||||
return _cairo_gstate_get_fill_rule (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3184,6 +3221,9 @@ cairo_get_fill_rule (cairo_t *cr)
|
||||
double
|
||||
cairo_get_line_width (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return 0.;
|
||||
|
||||
return _cairo_gstate_get_line_width (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3198,6 +3238,9 @@ cairo_get_line_width (cairo_t *cr)
|
||||
cairo_line_cap_t
|
||||
cairo_get_line_cap (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_line_cap_t) 0;
|
||||
|
||||
return _cairo_gstate_get_line_cap (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3212,6 +3255,9 @@ cairo_get_line_cap (cairo_t *cr)
|
||||
cairo_line_join_t
|
||||
cairo_get_line_join (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return (cairo_line_join_t) 0;
|
||||
|
||||
return _cairo_gstate_get_line_join (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3226,6 +3272,9 @@ cairo_get_line_join (cairo_t *cr)
|
||||
double
|
||||
cairo_get_miter_limit (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return 0.;
|
||||
|
||||
return _cairo_gstate_get_miter_limit (cr->gstate);
|
||||
}
|
||||
|
||||
@ -3239,6 +3288,11 @@ cairo_get_miter_limit (cairo_t *cr)
|
||||
void
|
||||
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
|
||||
{
|
||||
if (cr->status) {
|
||||
cairo_matrix_init_identity (matrix);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_gstate_get_matrix (cr->gstate, matrix);
|
||||
}
|
||||
slim_hidden_def (cairo_get_matrix);
|
||||
@ -3411,6 +3465,9 @@ cairo_append_path (cairo_t *cr,
|
||||
return;
|
||||
}
|
||||
|
||||
if (path->num_data == 0)
|
||||
return;
|
||||
|
||||
if (path->data == NULL) {
|
||||
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
|
||||
return;
|
||||
|
||||
@ -66,83 +66,21 @@
|
||||
#include "cairo.h"
|
||||
#include <pixman.h>
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#undef inline
|
||||
#define inline __inline__
|
||||
#endif
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
|
||||
# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
|
||||
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
|
||||
# define slim_hidden_int_name(name) INT_##name
|
||||
# define slim_hidden_proto1(name, internal) \
|
||||
extern __typeof (name) name \
|
||||
__asm__ (slim_hidden_asmname (internal))
|
||||
# define slim_hidden_def1(name, internal) \
|
||||
extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \
|
||||
__attribute__((__alias__(slim_hidden_asmname(internal))))
|
||||
# define slim_hidden_ulp slim_hidden_ulp1(__USER_LABEL_PREFIX__)
|
||||
# define slim_hidden_ulp1(x) slim_hidden_ulp2(x)
|
||||
# define slim_hidden_ulp2(x) #x
|
||||
# define slim_hidden_asmname(name) slim_hidden_asmname1(name)
|
||||
# define slim_hidden_asmname1(name) slim_hidden_ulp #name
|
||||
#else
|
||||
# define slim_hidden_proto(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void)
|
||||
# define slim_hidden_def(name) int _cairo_dummy_prototype(void)
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
|
||||
__attribute__((__format__(__printf__, fmt_index, va_index)))
|
||||
#else
|
||||
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
|
||||
#endif
|
||||
|
||||
/* slim_internal.h */
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
|
||||
#define cairo_private_no_warn __attribute__((__visibility__("hidden")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
#define cairo_private_no_warn __hidden
|
||||
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
|
||||
#define cairo_private_no_warn
|
||||
#endif
|
||||
|
||||
#ifndef WARN_UNUSED_RESULT
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
/* Add attribute(warn_unused_result) if supported */
|
||||
#define cairo_warn WARN_UNUSED_RESULT
|
||||
#define cairo_private cairo_private_no_warn cairo_warn
|
||||
|
||||
/* This macro allow us to deprecate a function by providing an alias
|
||||
for the old function name to the new function name. With this
|
||||
macro, binary compatibility is preserved. The macro only works on
|
||||
some platforms --- tough.
|
||||
|
||||
Meanwhile, new definitions in the public header file break the
|
||||
source code so that it will no longer link against the old
|
||||
symbols. Instead it will give a descriptive error message
|
||||
indicating that the old function has been deprecated by the new
|
||||
function.
|
||||
*/
|
||||
#if __GNUC__ >= 2 && defined(__ELF__)
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new) \
|
||||
extern __typeof (new) old \
|
||||
__asm__ ("" #old) \
|
||||
__attribute__((__alias__("" #new)))
|
||||
#else
|
||||
# define CAIRO_FUNCTION_ALIAS(old, new)
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
@ -184,8 +122,6 @@ do { \
|
||||
assert (NOT_REACHED); \
|
||||
} while (0)
|
||||
|
||||
#define CAIRO_REF_COUNT_INVALID ((unsigned int) -1)
|
||||
|
||||
#define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff))
|
||||
#define CAIRO_ALPHA_SHORT_IS_OPAQUE(alpha) ((alpha) >= 0xff00)
|
||||
#define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) <= 0.0)
|
||||
@ -242,6 +178,7 @@ be32_to_cpu(uint32_t v)
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-cache-private.h"
|
||||
#include "cairo-fixed-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
|
||||
typedef struct _cairo_region cairo_region_t;
|
||||
|
||||
@ -353,8 +290,11 @@ typedef struct _cairo_polygon {
|
||||
cairo_edge_t edges_embedded[8];
|
||||
} cairo_polygon_t;
|
||||
|
||||
typedef struct _cairo_spline {
|
||||
typedef struct _cairo_spline_knots {
|
||||
cairo_point_t a, b, c, d;
|
||||
} cairo_spline_knots_t;
|
||||
typedef struct _cairo_spline {
|
||||
cairo_spline_knots_t knots;
|
||||
|
||||
cairo_slope_t initial_slope;
|
||||
cairo_slope_t final_slope;
|
||||
@ -458,9 +398,9 @@ typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t;
|
||||
* glyph cache.
|
||||
*/
|
||||
typedef struct _cairo_unscaled_font {
|
||||
cairo_hash_entry_t hash_entry;
|
||||
unsigned int ref_count;
|
||||
const cairo_unscaled_font_backend_t *backend;
|
||||
cairo_hash_entry_t hash_entry;
|
||||
cairo_reference_count_t ref_count;
|
||||
const cairo_unscaled_font_backend_t *backend;
|
||||
} cairo_unscaled_font_t;
|
||||
|
||||
typedef struct _cairo_scaled_glyph {
|
||||
@ -484,7 +424,7 @@ struct _cairo_font_face {
|
||||
/* hash_entry must be first */
|
||||
cairo_hash_entry_t hash_entry;
|
||||
cairo_status_t status;
|
||||
unsigned int ref_count;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_user_data_array_t user_data;
|
||||
const cairo_font_face_backend_t *backend;
|
||||
};
|
||||
@ -529,6 +469,7 @@ typedef struct _cairo_scaled_font_subset {
|
||||
*/
|
||||
unsigned long *glyphs;
|
||||
unsigned long *to_unicode;
|
||||
char **glyph_names;
|
||||
unsigned int num_glyphs;
|
||||
cairo_bool_t is_composite;
|
||||
} cairo_scaled_font_subset_t;
|
||||
@ -957,14 +898,14 @@ typedef enum {
|
||||
#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_BEST
|
||||
|
||||
struct _cairo_pattern {
|
||||
cairo_pattern_type_t type;
|
||||
unsigned int ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_user_data_array_t user_data;
|
||||
cairo_pattern_type_t type;
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
cairo_matrix_t matrix;
|
||||
cairo_filter_t filter;
|
||||
cairo_extend_t extend;
|
||||
cairo_matrix_t matrix;
|
||||
cairo_filter_t filter;
|
||||
cairo_extend_t extend;
|
||||
};
|
||||
|
||||
typedef struct _cairo_solid_pattern {
|
||||
@ -1435,7 +1376,7 @@ _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font);
|
||||
cairo_private void
|
||||
_cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
|
||||
cairo_status_t status);
|
||||
|
||||
@ -1446,6 +1387,10 @@ cairo_private void
|
||||
_cairo_font_face_init (cairo_font_face_t *font_face,
|
||||
const cairo_font_face_backend_t *backend);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_font_face_set_error (cairo_font_face_t *font_face,
|
||||
cairo_status_t status);
|
||||
|
||||
cairo_private cairo_font_face_t *
|
||||
_cairo_toy_font_face_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
@ -1544,7 +1489,7 @@ _cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_close_path (cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_path_fixed_get_current_point (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t *x,
|
||||
cairo_fixed_t *y);
|
||||
@ -1698,7 +1643,7 @@ extern const cairo_private cairo_surface_t _cairo_surface_nil_read_error;
|
||||
extern const cairo_private cairo_surface_t _cairo_surface_nil_write_error;
|
||||
extern const cairo_private cairo_surface_t _cairo_surface_nil_file_not_found;
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_set_error (cairo_surface_t *surface,
|
||||
cairo_status_t status);
|
||||
|
||||
@ -2151,10 +2096,10 @@ _cairo_polygon_close (cairo_polygon_t *polygon);
|
||||
/* cairo_spline.c */
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_spline_init (cairo_spline_t *spline,
|
||||
cairo_point_t *a,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d);
|
||||
const cairo_point_t *a,
|
||||
const cairo_point_t *b,
|
||||
const cairo_point_t *c,
|
||||
const cairo_point_t *d);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_spline_decompose (cairo_spline_t *spline, double tolerance);
|
||||
@ -2175,6 +2120,9 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
|
||||
double *x2, double *y2,
|
||||
cairo_bool_t *is_tight);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private void
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
|
||||
|
||||
@ -2374,9 +2322,15 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
||||
uint16_t **result,
|
||||
int *items_written);
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_error (cairo_status_t status);
|
||||
|
||||
/* hide compiler warnings when discarding the return value */
|
||||
#define _cairo_error_throw(status) do { \
|
||||
cairo_status_t status__ = _cairo_error (status); \
|
||||
(void) status__; \
|
||||
} while (0)
|
||||
|
||||
/* Avoid unnecessary PLT entries. */
|
||||
slim_hidden_proto (cairo_clip_preserve);
|
||||
slim_hidden_proto (cairo_close_path);
|
||||
|
||||
@ -62,7 +62,7 @@ typedef struct _test_fallback_surface {
|
||||
cairo_surface_t *backing;
|
||||
} test_fallback_surface_t;
|
||||
|
||||
const cairo_private cairo_surface_backend_t test_fallback_surface_backend;
|
||||
static const cairo_surface_backend_t test_fallback_surface_backend;
|
||||
|
||||
slim_hidden_proto (_cairo_test_fallback_surface_create);
|
||||
|
||||
@ -81,7 +81,7 @@ _cairo_test_fallback_surface_create (cairo_content_t content,
|
||||
surface = malloc (sizeof (test_fallback_surface_t));
|
||||
if (surface == NULL) {
|
||||
cairo_surface_destroy (backing);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ _test_fallback_surface_get_extents (void *abstract_surface,
|
||||
return _cairo_surface_get_extents (surface->backing, rectangle);
|
||||
}
|
||||
|
||||
const cairo_surface_backend_t test_fallback_surface_backend = {
|
||||
static const cairo_surface_backend_t test_fallback_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
_test_fallback_surface_create_similar,
|
||||
_test_fallback_surface_finish,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user