mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 12:00:22 +01:00
Merge branch 'cairo-origin' into analysis-surface
With the string-array-stream stuff that this merge picks up, the analysis-surface branch is now passing all of the test suite again.
This commit is contained in:
commit
66ed9811cc
65 changed files with 1962 additions and 472 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
ChangeLog
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
|
|
|
|||
2
INSTALL
2
INSTALL
|
|
@ -16,7 +16,7 @@ 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 CVS rather than from a tar
|
||||
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.
|
||||
|
||||
|
|
|
|||
47
Makefile.am
47
Makefile.am
|
|
@ -11,6 +11,21 @@ EXTRA_DIST = \
|
|||
COPYING-LGPL-2.1 \
|
||||
COPYING-MPL-1.1 \
|
||||
cairo.pc.in
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/INSTALL \
|
||||
$(srcdir)/aclocal.m4 \
|
||||
$(srcdir)/autoscan.log \
|
||||
$(srcdir)/compile \
|
||||
$(srcdir)/config.guess \
|
||||
$(srcdir)/config.h.in \
|
||||
$(srcdir)/config.sub \
|
||||
$(srcdir)/configure.scan \
|
||||
$(srcdir)/depcomp \
|
||||
$(srcdir)/install-sh \
|
||||
$(srcdir)/ltmain.sh \
|
||||
$(srcdir)/missing \
|
||||
$(srcdir)/mkinstalldirs \
|
||||
`find "$(srcdir)" -type f -name Makefile.in -print`
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = cairo.pc
|
||||
|
|
@ -20,6 +35,30 @@ check-valgrind: all
|
|||
|
||||
DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
|
||||
|
||||
# Creating ChangeLog from git log:
|
||||
|
||||
MAINTAINERCLEANFILES += ChangeLog
|
||||
|
||||
EXTRA_DIST += ChangeLog
|
||||
|
||||
ChangeLog: $(srcdir)/ChangeLog
|
||||
|
||||
$(srcdir)/ChangeLog:
|
||||
@if test -d "$(srcdir)/.git"; then \
|
||||
(cd "$(srcdir)" && \
|
||||
./missing --run git-log) | fmt --split-only > $@.tmp \
|
||||
&& mv -f $@.tmp $@ \
|
||||
|| ($(RM) $@.tmp; \
|
||||
echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \
|
||||
(test -f $@ || echo git-log is required to generate this file >> $@)); \
|
||||
else \
|
||||
test -f $@ || \
|
||||
(echo A git checkout and git-log is required to generate ChangeLog >&2 && \
|
||||
echo A git checkout and git-log is required to generate this file >> $@); \
|
||||
fi
|
||||
|
||||
.PHONY: ChangeLog $(srcdir)/ChangeLog
|
||||
|
||||
# Some custom targets to make it easier to release things.
|
||||
# Use either:
|
||||
# make release-check
|
||||
|
|
@ -82,7 +121,7 @@ release-verify-newer:
|
|||
@echo -n "Checking that no $(VERSION) release already exists..."
|
||||
@ssh $(RELEASE_UPLOAD_HOST) test ! -e $(RELEASE_UPLOAD_DIR)/$(tar_file) \
|
||||
|| (echo "Ouch." && echo "Found: $(RELEASE_UPLOAD_HOST):$(RELEASE_UPLOAD_DIR)/$(tar_file)" \
|
||||
&& echo "Are you sure you have an updated CVS checkout?" \
|
||||
&& echo "Are you sure you have an updated checkout?" \
|
||||
&& echo "This should never happen." \
|
||||
&& false)
|
||||
@echo "Good."
|
||||
|
|
@ -104,9 +143,9 @@ release-upload: release-check $(tar_file) $(sha1_file) $(gpg_file)
|
|||
scp $(tar_file) $(sha1_file) $(gpg_file) $(RELEASE_UPLOAD_HOST):$(RELEASE_UPLOAD_DIR)
|
||||
mv $(tar_file) $(sha1_file) $(gpg_file) releases
|
||||
ssh $(RELEASE_UPLOAD_HOST) "rm -f $(RELEASE_UPLOAD_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_file) $(RELEASE_UPLOAD_DIR)/LATEST-$(PACKAGE)-$(VERSION)"
|
||||
$(CVS) tag RELEASE_$(CAIRO_VERSION_MAJOR)_$(CAIRO_VERSION_MINOR)_$(CAIRO_VERSION_MICRO)
|
||||
git tag -s $(CAIRO_VERSION_MAJOR).$(CAIRO_VERSION_MINOR).$(CAIRO_VERSION_MICRO)
|
||||
|
||||
release-publish: release-upload releases/$(sha1_file)
|
||||
release-publish-message: releases/$(sha1_file)
|
||||
@echo ""
|
||||
@echo "Please send an announcement to $(RELEASE_ANNOUNCE_LIST)"
|
||||
@echo "including the following:"
|
||||
|
|
@ -133,6 +172,8 @@ release-publish: release-upload releases/$(sha1_file)
|
|||
@echo "Last but not least, do not forget to bump up the micro"
|
||||
@echo "version component to the next (odd) number and commit."
|
||||
|
||||
release-publish: release-upload release-publish-message
|
||||
|
||||
# XXX: Depending on all here is rather overkill. We don't really need
|
||||
# the library built in order to create the documentation.
|
||||
docs-publish: all
|
||||
|
|
|
|||
26
RELEASING
26
RELEASING
|
|
@ -1,12 +1,7 @@
|
|||
Here are the steps to follow to create a new cairo release:
|
||||
|
||||
1) Ensure that there are no local, uncommitted modifications. The best
|
||||
thing to do here may be to begin with a fresh checkout from CVS:
|
||||
|
||||
cvs -d cairographics.org:/cvs/cairo co cairo
|
||||
|
||||
But it's probably good enough if "cvs -q update -Ad" generates no
|
||||
output.
|
||||
1) Ensure that there are no local, uncommitted modifications.
|
||||
It's probably good enough if "git diff" doesn't output anything.
|
||||
|
||||
2) Verify that the code passes "make distcheck"
|
||||
|
||||
|
|
@ -32,7 +27,10 @@ Here are the steps to follow to create a new cairo release:
|
|||
previous release tag:
|
||||
|
||||
find src/ -name '*.h' -not -name '*-private.h' -not -name 'cairoint.h' | \
|
||||
xargs cvs diff -r RELEASE_X_Y_Z
|
||||
xargs git diff X.Y.Z --
|
||||
|
||||
Note that for older releases made under CVS, the tag name is
|
||||
RELEASE_X_Y_Z instead.
|
||||
|
||||
4) Increment cairo_version_{minor|micro} and LT_{CURRENT|VERSION|AGE}
|
||||
in configure.in:
|
||||
|
|
@ -55,9 +53,8 @@ Here are the steps to follow to create a new cairo release:
|
|||
|
||||
5) Commit the changes to NEWS and configure.in
|
||||
|
||||
Don't forget to fill out the ChangeLog just like with any
|
||||
other commit. It's especially important to mention the new
|
||||
version number in the ChangeLog.
|
||||
It's especially important to mention the new version number in your
|
||||
commit log.
|
||||
|
||||
6) Run "make release-publish" which will perform the following steps
|
||||
for you:
|
||||
|
|
@ -71,8 +68,13 @@ Here are the steps to follow to create a new cairo release:
|
|||
* scp the three files to appear on http://cairographics.org/releases
|
||||
* Place local copies of the three files in the releases directory
|
||||
* Create a LATEST-package-version file (after deleting any old one)
|
||||
* Tag the entire source tree with a tag of the form RELEASE_X_Y_Z
|
||||
* Tag the entire source tree with a tag of the form X.Y.Z, and sign
|
||||
the tag with your GPG key (asks for your GPG password, and you
|
||||
may need to set GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL to match
|
||||
your public-key's setting or this fails.)
|
||||
* Provide some text for the release announcement (see below).
|
||||
If for some reason you lost this message, "make release-publish-message"
|
||||
prints it for you.
|
||||
|
||||
7) Increment cairo_version_micro to the next larger (odd) number in
|
||||
configure, and commit.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
AC_PREREQ(2.54)
|
||||
|
||||
# cairo package version number, (as distinct from shared library version)
|
||||
# An odd micro number indicates in-progress development, (eg. from CVS)
|
||||
# An odd micro number indicates in-progress development, (eg. from git/cvs)
|
||||
# An even micro number indicates a released version.
|
||||
m4_define(cairo_version_major, 1)
|
||||
m4_define(cairo_version_minor, 1)
|
||||
|
|
@ -810,6 +810,6 @@ if test x"$use_beos" = "xyes" ; then
|
|||
echo "$WARNING_MESSAGE" | sed 's/@BACKEND@/BeOS/'
|
||||
fi
|
||||
|
||||
if test x"$use_directfb" == "xyes" ; then
|
||||
if test x"$use_directfb" = "xyes" ; then
|
||||
echo "$WARNING_MESSAGE" | sed 's/@BACKEND@/DirectFB/'
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -33,10 +33,18 @@
|
|||
|
||||
#include "pixregionint.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// #define PIXMAN_CONVOLUTION
|
||||
// #define PIXMAN_INDEXED_FORMATS
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* #define PIXMAN_CONVOLUTION */
|
||||
/* #define PIXMAN_INDEXED_FORMATS */
|
||||
|
||||
static Bool
|
||||
PictureTransformPoint3d (pixman_transform_t *transform,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: fbedge.c,v 1.3 2005-08-02 01:01:24 vektor Exp $
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: fbedgeimp.h,v 1.2 2005-01-21 18:38:42 cworth Exp $
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: fbpict.c,v 1.8 2006-01-21 17:39:11 biesi Exp $
|
||||
*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -1151,7 +1149,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op,
|
|||
setupPackedReader(ws,wt,isrc,wsrc,workingSource);
|
||||
|
||||
/* get to word aligned */
|
||||
switch(!(long)dst&3)
|
||||
switch(~(long)dst&3)
|
||||
{
|
||||
case 1:
|
||||
readPackedSource(rs);
|
||||
|
|
@ -1227,7 +1225,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op,
|
|||
srcLine += srcStride;
|
||||
w = width*3;
|
||||
/* get to word aligned */
|
||||
switch(!(long)src&3)
|
||||
switch(~(long)src&3)
|
||||
{
|
||||
case 1:
|
||||
rd=alphamaskCombine24(*src++, *dst)>>8;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: fbpict.h,v 1.2 2005-09-12 12:55:11 otaylor Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: icpixels.c,v 1.9 2005-06-25 03:13:19 jrmuizel Exp $
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: ictrap.c,v 1.27 2005-08-28 02:32:57 vektor Exp $
|
||||
*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ typedef pixman_triangle_t xTriangle;
|
|||
#define FB_SHIFT IC_SHIFT
|
||||
#define FB_MASK IC_MASK
|
||||
#define FB_ALLONES IC_ALLONES
|
||||
#define FbMaskBits IcMaskBits
|
||||
*/
|
||||
//#define FbMaskBits IcMaskBits
|
||||
|
||||
/* XXX: We changed some function and field names which makes for some
|
||||
* ugly hacks... */
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/* $Id: pixman.h,v 1.25 2006-01-05 00:26:10 cworth Exp $ */
|
||||
|
||||
/* libic.h */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ SOFTWARE.
|
|||
#endif
|
||||
|
||||
#undef assert
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_PIXREGION
|
||||
#define assert(expr) {if (!(expr)) \
|
||||
FatalError("Assertion failed file %s, line %d: expr\n", \
|
||||
__FILE__, __LINE__); }
|
||||
|
|
@ -208,7 +208,7 @@ if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
|
|||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_PIXREGION
|
||||
int
|
||||
pixman_region16_print(rgn)
|
||||
pixman_region16_t * rgn;
|
||||
|
|
@ -302,7 +302,7 @@ pixman_region16_valid(reg)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
#endif /* DEBUG_PIXREGION */
|
||||
|
||||
|
||||
/* Create a new empty region */
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/* $Id: pixregionint.h,v 1.7 2004-04-16 15:32:53 cworth Exp $ */
|
||||
|
||||
#ifndef _PIXREGIONINT_H_
|
||||
#define _PIXREGIONINT_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: renderedge.c,v 1.2 2005-01-21 18:26:28 cworth Exp $
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: renderedge.h,v 1.3 2005-02-21 21:29:22 cworth Exp $
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ libcairo_beos_sources =
|
|||
if CAIRO_HAS_BEOS_SURFACE
|
||||
libcairo_beos_headers = cairo-beos.h
|
||||
libcairo_beos_sources += cairo-beos-surface.cpp
|
||||
|
||||
noinst_LTLIBRARIES = libcairo_beos.la
|
||||
libcairo_beos_la_SOURCES = $(libcairo_beos_sources)
|
||||
# BeOS system headers trigger this warning
|
||||
libcairo_beos_la_CXXFLAGS = -Wno-multichar
|
||||
endif
|
||||
|
||||
if CAIRO_HAS_GLITZ_SURFACE
|
||||
|
|
@ -129,6 +134,7 @@ libcairo_la_SOURCES = \
|
|||
cairo-arc.c \
|
||||
cairo-arc-private.h \
|
||||
cairo-array.c \
|
||||
cairo-base85-stream.c \
|
||||
cairo-cache.c \
|
||||
cairo-cache-private.h \
|
||||
cairo-clip.c \
|
||||
|
|
@ -145,6 +151,7 @@ libcairo_la_SOURCES = \
|
|||
cairo-hash-private.h \
|
||||
cairo-hull.c \
|
||||
cairo-image-surface.c \
|
||||
cairo-lzw.c \
|
||||
cairo-matrix.c \
|
||||
cairo-path.c \
|
||||
cairo-path-bounds.c \
|
||||
|
|
@ -193,15 +200,12 @@ libcairo_la_SOURCES = \
|
|||
cairoint.h
|
||||
|
||||
libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols)
|
||||
# this -Wno-multichar line is really just for the beos surface, because the
|
||||
# system headers trigger this warning.
|
||||
libcairo_la_CXXFLAGS = -Wno-multichar
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(top_srcdir)/pixman/src $(CAIRO_CFLAGS)
|
||||
|
||||
libcairo_la_LIBADD = $(top_builddir)/pixman/src/libpixman.la $(CAIRO_LIBS)
|
||||
libcairo_la_LIBADD = $(top_builddir)/pixman/src/libpixman.la $(CAIRO_LIBS) $(noinst_LTLIBRARIES)
|
||||
|
||||
libcairo_la_DEPENDENCIES = $(cairo_def_dependency) $(top_builddir)/pixman/src/libpixman.la
|
||||
libcairo_la_DEPENDENCIES = $(cairo_def_dependency) $(top_builddir)/pixman/src/libpixman.la $(noinst_LTLIBRARIES)
|
||||
|
||||
EXTRA_DIST = \
|
||||
cairo.def
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
NULL, /* create_similar */
|
||||
NULL, /* finish_surface */
|
||||
NULL, /* acquire_source_image */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,16 @@
|
|||
#include "cairo.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
/*
|
||||
* FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
|
||||
* here so we can use older SDKs.
|
||||
*/
|
||||
#ifndef FixedToFloat
|
||||
#define fixed1 ((Fixed) 0x00010000L)
|
||||
#define FixedToFloat(a) ((float)(a) / fixed1)
|
||||
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
|
||||
typedef struct _cairo_atsui_font cairo_atsui_font_t;
|
||||
|
||||
|
|
@ -133,7 +143,7 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle, const cairo_matrix_t *scale)
|
|||
ATSUStyle style;
|
||||
OSStatus err;
|
||||
|
||||
// Set the style's size
|
||||
/* Set the style's size */
|
||||
CGAffineTransform theTransform =
|
||||
CGAffineTransformMakeWithCairoFontScale(scale);
|
||||
Fixed theSize =
|
||||
|
|
@ -175,7 +185,7 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
|
|||
extents.height = metrics.capHeight;
|
||||
extents.max_x_advance = metrics.maxAdvanceWidth;
|
||||
|
||||
// The FT backend doesn't handle max_y_advance either, so we'll ignore it for now.
|
||||
/* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
|
||||
extents.max_y_advance = 0.0;
|
||||
|
||||
_cairo_scaled_font_set_metrics (&font->base, &extents);
|
||||
|
|
@ -276,7 +286,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
|||
kFontNoLanguageCode, &fontID);
|
||||
|
||||
if (err != noErr) {
|
||||
// couldn't get the font - remap css names and try again
|
||||
/* couldn't get the font - remap css names and try again */
|
||||
|
||||
if (!strcmp(family, "serif"))
|
||||
family = "Times";
|
||||
|
|
@ -288,7 +298,7 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face,
|
|||
family = "Gadget";
|
||||
else if (!strcmp(family, "monospace"))
|
||||
family = "Courier";
|
||||
else // anything else - return error instead?
|
||||
else /* anything else - return error instead? */
|
||||
family = "Courier";
|
||||
|
||||
err = ATSUFindFontFromName(family, strlen(family),
|
||||
|
|
@ -505,7 +515,7 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
|
|||
|
||||
err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
|
||||
|
||||
// Set the style for all of the text
|
||||
/* Set the style for all of the text */
|
||||
err = ATSUSetRunStyle(textLayout,
|
||||
font->style, kATSUFromTextBeginning, kATSUToTextEnd);
|
||||
|
||||
|
|
@ -566,7 +576,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
&rect,
|
||||
&extra);
|
||||
|
||||
// Create a CGBitmapContext for the dest surface for drawing into
|
||||
/* Create a CGBitmapContext for the dest surface for drawing into */
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
|
||||
|
|
@ -592,7 +602,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
CGContextSetFontSize(myBitmapContext, 1.0);
|
||||
CGContextSetTextMatrix(myBitmapContext, textTransform);
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_SOLID &&
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID &&
|
||||
_cairo_pattern_is_opaque_solid(pattern))
|
||||
{
|
||||
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
|
||||
|
|
@ -634,11 +644,12 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
/* XXX: Need to get the text clipped */
|
||||
}
|
||||
|
||||
// TODO - bold and italic text
|
||||
//
|
||||
// We could draw the text using ATSUI and get bold, italics
|
||||
// etc. for free, but ATSUI does a lot of text layout work
|
||||
// that we don't really need...
|
||||
/* TODO - bold and italic text
|
||||
*
|
||||
* We could draw the text using ATSUI and get bold, italics
|
||||
* etc. for free, but ATSUI does a lot of text layout work
|
||||
* that we don't really need...
|
||||
*/
|
||||
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
|
|
@ -664,6 +675,7 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
|||
}
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_ATSUI,
|
||||
_cairo_atsui_font_create_toy,
|
||||
_cairo_atsui_font_fini,
|
||||
_cairo_atsui_font_scaled_glyph_init,
|
||||
|
|
|
|||
130
src/cairo-base85-stream.c
Normal file
130
src/cairo-base85-stream.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/* cairo_output_stream.c: Output stream abstraction
|
||||
*
|
||||
* 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 cairo_output_stream.c as distributed with the
|
||||
* cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _cairo_base85_stream {
|
||||
cairo_output_stream_t *output;
|
||||
unsigned char four_tuple[4];
|
||||
int pending;
|
||||
} cairo_base85_stream_t;
|
||||
|
||||
static void
|
||||
_expand_four_tuple_to_five (unsigned char four_tuple[4],
|
||||
unsigned char five_tuple[5],
|
||||
cairo_bool_t *all_zero)
|
||||
{
|
||||
uint32_t value;
|
||||
int digit, i;
|
||||
|
||||
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
|
||||
if (all_zero)
|
||||
*all_zero = TRUE;
|
||||
for (i = 0; i < 5; i++) {
|
||||
digit = value % 85;
|
||||
if (digit != 0 && all_zero)
|
||||
*all_zero = FALSE;
|
||||
five_tuple[4-i] = digit + 33;
|
||||
value = value / 85;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_write_data (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_base85_stream_t *stream = closure;
|
||||
const unsigned char *ptr = data;
|
||||
unsigned char five_tuple[5];
|
||||
cairo_bool_t is_zero;
|
||||
|
||||
while (length) {
|
||||
stream->four_tuple[stream->pending++] = *ptr++;
|
||||
length--;
|
||||
if (stream->pending == 4) {
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero);
|
||||
if (is_zero)
|
||||
_cairo_output_stream_write (stream->output, "z", 1);
|
||||
else
|
||||
_cairo_output_stream_write (stream->output, five_tuple, 5);
|
||||
stream->pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_close (void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_base85_stream_t *stream = closure;
|
||||
unsigned char five_tuple[5];
|
||||
|
||||
if (stream->pending) {
|
||||
memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending);
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL);
|
||||
_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
|
||||
}
|
||||
|
||||
/* Mark end of base85 data */
|
||||
_cairo_output_stream_printf (stream->output, "~>");
|
||||
|
||||
status = _cairo_output_stream_get_status (stream->output);
|
||||
|
||||
free (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_base85_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_base85_stream_t));
|
||||
if (stream == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
|
||||
stream->output = output;
|
||||
stream->pending = 0;
|
||||
|
||||
return _cairo_output_stream_create (_cairo_base85_stream_write_data,
|
||||
_cairo_base85_stream_close,
|
||||
stream);
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +70,9 @@ struct cairo_beos_surface_t {
|
|||
BBitmap* bitmap;
|
||||
|
||||
|
||||
// If true, surface and view should be deleted when this surface is
|
||||
// destroyed
|
||||
bool owns_bitmap_view;
|
||||
};
|
||||
|
||||
class AutoLockView {
|
||||
|
|
@ -92,6 +95,11 @@ class AutoLockView {
|
|||
bool mOK;
|
||||
};
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_internal (BView* view,
|
||||
BBitmap* bmp,
|
||||
bool owns_bitmap_view = false);
|
||||
|
||||
static BRect
|
||||
_cairo_rect_to_brect (const cairo_rectangle_t* rect)
|
||||
{
|
||||
|
|
@ -359,6 +367,7 @@ _cairo_image_surface_to_bitmap (cairo_image_surface_t* surface)
|
|||
return data;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -414,10 +423,76 @@ _cairo_op_to_be_op (cairo_operator_t cairo_op,
|
|||
};
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
fprintf(stderr, "Creating similar\n");
|
||||
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
|
||||
if (width <= 0)
|
||||
width = 1;
|
||||
if (height <= 0)
|
||||
height = 1;
|
||||
|
||||
BRect rect(0.0, 0.0, width - 1, height - 1);
|
||||
BBitmap* bmp;
|
||||
switch (content) {
|
||||
case CAIRO_CONTENT_ALPHA:
|
||||
// Can't support this natively
|
||||
return _cairo_image_surface_create_with_content(content, width,
|
||||
height);
|
||||
case CAIRO_CONTENT_COLOR_ALPHA:
|
||||
bmp = new BBitmap(rect, B_RGBA32, true);
|
||||
break;
|
||||
case CAIRO_CONTENT_COLOR:
|
||||
// Match the color depth
|
||||
if (surface->bitmap) {
|
||||
color_space space = surface->bitmap->ColorSpace();
|
||||
// No alpha was requested -> make sure not to return
|
||||
// a surface with alpha
|
||||
if (space == B_RGBA32)
|
||||
space = B_RGB32;
|
||||
if (space == B_RGBA15)
|
||||
space = B_RGB15;
|
||||
bmp = new BBitmap(rect, space, true);
|
||||
} else {
|
||||
BScreen scr(surface->view->Window());
|
||||
color_space space = B_RGB32;
|
||||
if (scr.IsValid())
|
||||
space = scr.ColorSpace();
|
||||
bmp = new BBitmap(rect, space, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
|
||||
};
|
||||
BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
|
||||
bmp->AddChild(view);
|
||||
return _cairo_beos_surface_create_internal(view, bmp, true);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_beos_surface_finish (void *abstract_surface)
|
||||
{
|
||||
// Nothing to do
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
if (surface->owns_bitmap_view) {
|
||||
if (surface->bitmap)
|
||||
surface->bitmap->RemoveChild(surface->view);
|
||||
|
||||
delete surface->view;
|
||||
delete surface->bitmap;
|
||||
|
||||
surface->view = NULL;
|
||||
surface->bitmap = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -549,13 +624,12 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface,
|
|||
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
|
||||
AutoLockView locker(surface->view);
|
||||
if (!locker)
|
||||
return;
|
||||
|
||||
|
||||
BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
|
||||
|
||||
surface->view->PushState();
|
||||
|
||||
surface->view->SetDrawingMode(B_OP_COPY);
|
||||
|
|
@ -570,18 +644,18 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_beos_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
_cairo_beos_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
dst);
|
||||
|
|
@ -598,7 +672,7 @@ _cairo_beos_composite (cairo_operator_t op,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
// XXX should eventually support the others
|
||||
if (src->type != CAIRO_PATTERN_SURFACE ||
|
||||
if (src->type != CAIRO_PATTERN_TYPE_SURFACE ||
|
||||
src->extend != CAIRO_EXTEND_NONE)
|
||||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
|
@ -617,63 +691,95 @@ _cairo_beos_composite (cairo_operator_t op,
|
|||
|
||||
cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)->
|
||||
surface;
|
||||
if (_cairo_surface_is_image(src_surface)) {
|
||||
fprintf(stderr, "Composite\n");
|
||||
|
||||
// Draw it on screen.
|
||||
// Get a bitmap
|
||||
BBitmap* bmp = NULL;
|
||||
bool free_bmp = false;
|
||||
if (_cairo_surface_is_image(src_surface)) {
|
||||
cairo_image_surface_t* img_surface =
|
||||
reinterpret_cast<cairo_image_surface_t*>(src_surface);
|
||||
|
||||
BBitmap* bmp = _cairo_image_surface_to_bitmap(img_surface);
|
||||
surface->view->PushState();
|
||||
|
||||
// If our image rect is only a subrect of the desired size, and we
|
||||
// aren't using B_OP_ALPHA, then we need to fill the rect first.
|
||||
if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
|
||||
rgb_color black = { 0, 0, 0, 0 };
|
||||
|
||||
surface->view->SetDrawingMode(mode);
|
||||
surface->view->SetHighColor(black);
|
||||
surface->view->FillRect(dstRect);
|
||||
}
|
||||
|
||||
if (mode == B_OP_ALPHA && img_surface->format != CAIRO_FORMAT_ARGB32) {
|
||||
mode = B_OP_COPY;
|
||||
|
||||
}
|
||||
surface->view->SetDrawingMode(mode);
|
||||
|
||||
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
|
||||
else
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
surface->view->DrawBitmap(bmp, srcRect, dstRect);
|
||||
|
||||
surface->view->PopState();
|
||||
delete bmp;
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
bmp = _cairo_image_surface_to_bitmap(img_surface);
|
||||
free_bmp = true;
|
||||
} else if (src_surface->backend == surface->base.backend) {
|
||||
cairo_beos_surface_t *beos_surface =
|
||||
reinterpret_cast<cairo_beos_surface_t*>(src_surface);
|
||||
if (beos_surface->bitmap) {
|
||||
AutoLockView locker(beos_surface->view);
|
||||
if (locker)
|
||||
beos_surface->view->Sync();
|
||||
bmp = beos_surface->bitmap;
|
||||
} else {
|
||||
_cairo_beos_view_to_bitmap(surface->view, &bmp);
|
||||
free_bmp = true;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (!bmp)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
// So, BeOS seems to screw up painting an opaque bitmap onto a
|
||||
// translucent one (it makes them partly transparent). Just return
|
||||
// unsupported.
|
||||
if (bmp->ColorSpace() == B_RGB32 && surface->bitmap &&
|
||||
surface->bitmap->ColorSpace() == B_RGBA32 &&
|
||||
(mode == B_OP_COPY || mode == B_OP_ALPHA))
|
||||
{
|
||||
if (free_bmp)
|
||||
delete bmp;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Composite\n");
|
||||
|
||||
// Draw it on screen.
|
||||
surface->view->PushState();
|
||||
|
||||
// If our image rect is only a subrect of the desired size, and we
|
||||
// aren't using B_OP_ALPHA, then we need to fill the rect first.
|
||||
if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
|
||||
rgb_color black = { 0, 0, 0, 0 };
|
||||
|
||||
surface->view->SetDrawingMode(mode);
|
||||
surface->view->SetHighColor(black);
|
||||
surface->view->FillRect(dstRect);
|
||||
}
|
||||
|
||||
if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) {
|
||||
mode = B_OP_COPY;
|
||||
}
|
||||
surface->view->SetDrawingMode(mode);
|
||||
|
||||
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
|
||||
else
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
surface->view->DrawBitmap(bmp, srcRect, dstRect);
|
||||
|
||||
surface->view->PopState();
|
||||
|
||||
if (free_bmp)
|
||||
delete bmp;
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_cairo_beos_fill_rectangle (cairo_beos_surface_t *surface,
|
||||
cairo_rectangle_t *rect)
|
||||
_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface,
|
||||
cairo_rectangle_t *rect)
|
||||
{
|
||||
BRect brect(_cairo_rect_to_brect(rect));
|
||||
surface->view->FillRect(brect);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_beos_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
fprintf(stderr, "Drawing %i rectangles\n", num_rects);
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
|
|
@ -716,7 +822,7 @@ _cairo_beos_fill_rectangles (void *abstract_surface,
|
|||
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
for (int i = 0; i < num_rects; ++i) {
|
||||
_cairo_beos_fill_rectangle(surface, &rects[i]);
|
||||
_cairo_beos_surface_fill_rectangle(surface, &rects[i]);
|
||||
}
|
||||
|
||||
surface->view->PopState();
|
||||
|
|
@ -777,15 +883,16 @@ _cairo_beos_surface_get_extents (void *abstract_surface,
|
|||
}
|
||||
|
||||
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
||||
NULL, /* create_similar */
|
||||
CAIRO_SURFACE_TYPE_BEOS,
|
||||
_cairo_beos_surface_create_similar,
|
||||
_cairo_beos_surface_finish,
|
||||
_cairo_beos_surface_acquire_source_image,
|
||||
_cairo_beos_surface_release_source_image,
|
||||
_cairo_beos_surface_acquire_dest_image,
|
||||
_cairo_beos_surface_release_dest_image,
|
||||
NULL, /* clone_similar */
|
||||
_cairo_beos_composite, /* composite */
|
||||
_cairo_beos_fill_rectangles,
|
||||
_cairo_beos_surface_composite, /* composite */
|
||||
_cairo_beos_surface_fill_rectangles,
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
|
|
@ -806,6 +913,28 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
|||
NULL /* show_glyphs */
|
||||
};
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_internal (BView* view,
|
||||
BBitmap* bmp,
|
||||
bool owns_bitmap_view)
|
||||
{
|
||||
// Must use malloc, because cairo code will use free() on the surface
|
||||
cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
|
||||
malloc(sizeof(cairo_beos_surface_t)));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
|
||||
}
|
||||
|
||||
_cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
|
||||
|
||||
surface->view = view;
|
||||
surface->bitmap = bmp;
|
||||
surface->owns_bitmap_view = owns_bitmap_view;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_beos_surface_create:
|
||||
* @view: The view to draw on
|
||||
|
|
@ -842,20 +971,7 @@ cairo_surface_t *
|
|||
cairo_beos_surface_create_for_bitmap (BView* view,
|
||||
BBitmap* bmp)
|
||||
{
|
||||
// Must use malloc, because cairo code will use free() on the surface
|
||||
cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
|
||||
malloc(sizeof(cairo_beos_surface_t)));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
|
||||
}
|
||||
|
||||
_cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
|
||||
|
||||
surface->view = view;
|
||||
surface->bitmap = bmp;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
return _cairo_beos_surface_create_internal(view, bmp);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ typedef struct _cairo_cache_entry {
|
|||
} cairo_cache_entry_t;
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_cache_keys_equal_func_t) (void *key_a, void *key_b);
|
||||
(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef void
|
||||
(*cairo_cache_callback_func_t) (void *entry,
|
||||
|
|
|
|||
|
|
@ -248,8 +248,10 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
|
||||
if (status)
|
||||
if (status) {
|
||||
free (clip_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
clip_path->ref_count = 1;
|
||||
clip_path->fill_rule = fill_rule;
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ static inline int cairo_to_directfb_format(cairo_format_t format ) {
|
|||
return DSPF_A1;
|
||||
default:
|
||||
{
|
||||
//assert(0);
|
||||
/*assert(0);*/
|
||||
return DSPF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
|
@ -483,9 +483,9 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
if( _dfb_set_operator(op,surface->buffer) == DFB_UNSUPPORTED )
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (src_pattern->type == CAIRO_PATTERN_SOLID ) {
|
||||
if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID ) {
|
||||
|
||||
} else if (src_pattern->type != CAIRO_PATTERN_SURFACE ||
|
||||
} else if (src_pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
|
||||
src_pattern->extend != CAIRO_EXTEND_NONE) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
|
@ -494,7 +494,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
|||
/* FIXME: When we fully support RENDER style 4-channel
|
||||
* masks we need to check r/g/b != 1.0.
|
||||
*/
|
||||
if (mask_pattern->type != CAIRO_PATTERN_SOLID)
|
||||
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
|
||||
|
|
@ -662,6 +662,7 @@ _cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
|
|||
|
||||
|
||||
static const cairo_surface_backend_t cairo_directfb_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_DIRECTFB,
|
||||
_cairo_directfb_surface_create_similar,
|
||||
_cairo_directfb_surface_finish,
|
||||
_cairo_directfb_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -130,6 +130,12 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
|
|||
free (font_face);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_face_get_type:
|
||||
* @font_face: a #cairo_font_face_t
|
||||
*
|
||||
* Return value: The type of @font_face. See #cairo_font_type_t.
|
||||
**/
|
||||
cairo_font_type_t
|
||||
cairo_font_face_get_type (cairo_font_face_t *font_face)
|
||||
{
|
||||
|
|
@ -204,8 +210,8 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
|||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (void *key_a,
|
||||
void *key_b);
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b);
|
||||
|
||||
/* We maintain a hash table from family/weight/slant =>
|
||||
* cairo_font_face_t for cairo_toy_font_t. The primary purpose of
|
||||
|
|
@ -306,11 +312,11 @@ _cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
|
|||
}
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (void *key_a,
|
||||
void *key_b)
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b)
|
||||
{
|
||||
cairo_toy_font_face_t *face_a = key_a;
|
||||
cairo_toy_font_face_t *face_b = key_b;
|
||||
const cairo_toy_font_face_t *face_a = key_a;
|
||||
const cairo_toy_font_face_t *face_b = key_b;
|
||||
|
||||
return (strcmp (face_a->family, face_b->family) == 0 &&
|
||||
face_a->slant == face_b->slant &&
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ struct _cairo_ft_unscaled_font {
|
|||
};
|
||||
|
||||
static int
|
||||
_cairo_ft_unscaled_font_keys_equal (void *key_a,
|
||||
void *key_b);
|
||||
_cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
||||
const void *key_b);
|
||||
|
||||
static void
|
||||
_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
|
||||
|
|
@ -365,11 +365,11 @@ _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
|
|||
}
|
||||
|
||||
static int
|
||||
_cairo_ft_unscaled_font_keys_equal (void *key_a,
|
||||
void *key_b)
|
||||
_cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
||||
const void *key_b)
|
||||
{
|
||||
cairo_ft_unscaled_font_t *unscaled_a = key_a;
|
||||
cairo_ft_unscaled_font_t *unscaled_b = key_b;
|
||||
const cairo_ft_unscaled_font_t *unscaled_a = key_a;
|
||||
const cairo_ft_unscaled_font_t *unscaled_b = key_b;
|
||||
|
||||
return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0 &&
|
||||
unscaled_a->id == unscaled_b->id);
|
||||
|
|
@ -1901,6 +1901,7 @@ _cairo_ft_show_glyphs (void *abstract_font,
|
|||
}
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_FT,
|
||||
_cairo_ft_scaled_font_create_toy,
|
||||
_cairo_ft_scaled_font_fini,
|
||||
_cairo_ft_scaled_glyph_init,
|
||||
|
|
|
|||
|
|
@ -551,8 +551,8 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
attr->acquired = FALSE;
|
||||
|
||||
switch (pattern->type) {
|
||||
case CAIRO_PATTERN_LINEAR:
|
||||
case CAIRO_PATTERN_RADIAL: {
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
case CAIRO_PATTERN_TYPE_RADIAL: {
|
||||
cairo_gradient_pattern_t *gradient =
|
||||
(cairo_gradient_pattern_t *) pattern;
|
||||
char *data;
|
||||
|
|
@ -587,7 +587,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))
|
||||
break;
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_RADIAL)
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL)
|
||||
n_base_params = 6;
|
||||
else
|
||||
n_base_params = 4;
|
||||
|
|
@ -639,7 +639,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
|
||||
glitz_buffer_destroy (buffer);
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_LINEAR)
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
|
||||
{
|
||||
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
|
||||
|
||||
|
|
@ -776,8 +776,8 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
|
|||
* information in mask, so this will need to change when we
|
||||
* support RENDER-style 4-channel masks. */
|
||||
|
||||
if (src->type == CAIRO_PATTERN_SOLID &&
|
||||
mask->type == CAIRO_PATTERN_SOLID)
|
||||
if (src->type == CAIRO_PATTERN_TYPE_SOLID &&
|
||||
mask->type == CAIRO_PATTERN_TYPE_SOLID)
|
||||
{
|
||||
cairo_color_t combined;
|
||||
cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
|
||||
|
|
@ -1018,7 +1018,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
if (_glitz_ensure_target (dst->surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_SURFACE)
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
|
||||
{
|
||||
_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
|
||||
|
||||
|
|
@ -2121,6 +2121,7 @@ _cairo_glitz_surface_flush (void *abstract_surface)
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_GLITZ,
|
||||
_cairo_glitz_surface_create_similar,
|
||||
_cairo_glitz_surface_finish,
|
||||
_cairo_glitz_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ typedef struct _cairo_hash_entry {
|
|||
} cairo_hash_entry_t;
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_keys_equal_func_t) (void *key_a, void *key_b);
|
||||
(*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_predicate_func_t) (void *entry);
|
||||
|
|
|
|||
|
|
@ -903,6 +903,7 @@ _cairo_surface_is_image (const cairo_surface_t *surface)
|
|||
}
|
||||
|
||||
const cairo_surface_backend_t cairo_image_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
_cairo_image_surface_create_similar,
|
||||
_cairo_image_surface_finish,
|
||||
_cairo_image_surface_acquire_source_image,
|
||||
|
|
|
|||
400
src/cairo-lzw.c
Normal file
400
src/cairo-lzw.c
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 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>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _lzw_buf {
|
||||
cairo_status_t status;
|
||||
|
||||
unsigned char *data;
|
||||
int data_size;
|
||||
int num_data;
|
||||
uint32_t pending;
|
||||
int pending_bits;
|
||||
} lzw_buf_t;
|
||||
|
||||
/* An lzw_buf_t is a simple, growable chunk of memory for holding
|
||||
* variable-size objects of up to 16 bits each.
|
||||
*
|
||||
* Initialize an lzw_buf_t to the given size in bytes.
|
||||
*
|
||||
* To store objects into the lzw_buf_t, call _lzw_buf_store_bits and
|
||||
* when finished, call _lzw_buf_store_pending, (which flushes out the
|
||||
* last few bits that hadn't yet made a complete byte yet).
|
||||
*
|
||||
* Instead of returning failure from any functions, lzw_buf_t provides
|
||||
* a status value that the caller can query, (and should query at
|
||||
* least once when done with the object). The status value will be
|
||||
* either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY;
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_init (lzw_buf_t *buf, int size)
|
||||
{
|
||||
if (size == 0)
|
||||
size = 16;
|
||||
|
||||
buf->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
buf->data = malloc (size);
|
||||
if (buf->data == NULL) {
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
buf->data_size = size;
|
||||
buf->num_data = 0;
|
||||
buf->pending = 0;
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* Increase the buffer size by doubling.
|
||||
*
|
||||
* Returns CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY
|
||||
*/
|
||||
static cairo_status_t
|
||||
_lzw_buf_grow (lzw_buf_t *buf)
|
||||
{
|
||||
int new_size = buf->data_size * 2;
|
||||
unsigned char *new_data;
|
||||
|
||||
if (buf->status)
|
||||
return buf->status;
|
||||
|
||||
new_data = realloc (buf->data, new_size);
|
||||
if (new_data == NULL) {
|
||||
free (buf->data);
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return buf->status;
|
||||
}
|
||||
|
||||
buf->data = new_data;
|
||||
buf->data_size = new_size;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Store the lowest num_bits bits of values into buf.
|
||||
*
|
||||
* NOTE: The bits of value above size_in_bits must be 0, (so don't lie
|
||||
* about the size).
|
||||
*
|
||||
* See also _lzw_buf_store_pending which must be called after the last
|
||||
* call to _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_bits (lzw_buf_t *buf, uint16_t value, int num_bits)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (value <= (1 << num_bits) - 1);
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
buf->pending = (buf->pending << num_bits) | value;
|
||||
buf->pending_bits += num_bits;
|
||||
|
||||
while (buf->pending_bits >= 8) {
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
buf->data[buf->num_data++] = buf->pending >> (buf->pending_bits - 8);
|
||||
buf->pending_bits -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the last remaining pending bits into the buffer.
|
||||
*
|
||||
* NOTE: This function must be called after the last call to
|
||||
* _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_pending (lzw_buf_t *buf)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
if (buf->pending_bits == 0)
|
||||
return;
|
||||
|
||||
assert (buf->pending_bits < 8);
|
||||
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
|
||||
buf->data[buf->num_data++] = buf->pending << (8 - buf->pending_bits);
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* LZW defines a few magic code values */
|
||||
#define LZW_CODE_CLEAR_TABLE 256
|
||||
#define LZW_CODE_EOD 257
|
||||
#define LZW_CODE_FIRST 258
|
||||
|
||||
/* We pack three separate values into a symbol as follows:
|
||||
*
|
||||
* 12 bits (31 down to 20): CODE: code value used to represent this symbol
|
||||
* 12 bits (19 down to 8): PREV: previous code value in chain
|
||||
* 8 bits ( 7 down to 0): NEXT: next byte value in chain
|
||||
*/
|
||||
typedef uint32_t lzw_symbol_t;
|
||||
|
||||
#define LZW_SYMBOL_SET(sym, prev, next) ((sym) = ((prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_SET_CODE(sym, code, prev, next) ((sym) = ((code << 20)|(prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_GET_CODE(sym) (((sym) >> 20))
|
||||
#define LZW_SYMBOL_GET_PREV(sym) (((sym) >> 8) & 0x7ff)
|
||||
#define LZW_SYMBOL_GET_BYTE(sym) (((sym) >> 0) & 0x0ff)
|
||||
|
||||
/* The PREV+NEXT fields can be seen as the key used to fetch values
|
||||
* from the hash table, while the code is the value fetched.
|
||||
*/
|
||||
#define LZW_SYMBOL_KEY_MASK 0x000fffff
|
||||
|
||||
/* Since code values are only stored starting with 258 we can safely
|
||||
* use a zero value to represent free slots in the hash table. */
|
||||
#define LZW_SYMBOL_FREE 0x00000000
|
||||
|
||||
/* These really aren't very free for modifying. First, the PostScript
|
||||
* specification sets the 9-12 bit range. Second, the encoding of
|
||||
* lzw_symbol_t above also relies on 2 of LZW_BITS_MAX plus one byte
|
||||
* fitting within 32 bits.
|
||||
*
|
||||
* But other than that, the LZW compression scheme could function with
|
||||
* more bits per code.
|
||||
*/
|
||||
#define LZW_BITS_MIN 9
|
||||
#define LZW_BITS_MAX 12
|
||||
#define LZW_BITS_BOUNDARY(bits) ((1<<(bits))-1)
|
||||
#define LZW_MAX_SYMBOLS (1<<LZW_BITS_MAX)
|
||||
|
||||
#define LZW_SYMBOL_TABLE_SIZE 9013
|
||||
#define LZW_SYMBOL_MOD1 LZW_SYMBOL_TABLE_SIZE
|
||||
#define LZW_SYMBOL_MOD2 9011
|
||||
|
||||
typedef struct _lzw_symbol_table {
|
||||
lzw_symbol_t table[LZW_SYMBOL_TABLE_SIZE];
|
||||
} lzw_symbol_table_t;
|
||||
|
||||
/* Initialize the hash table to entirely empty */
|
||||
static void
|
||||
_lzw_symbol_table_init (lzw_symbol_table_t *table)
|
||||
{
|
||||
memset (table->table, 0, LZW_SYMBOL_TABLE_SIZE * sizeof (lzw_symbol_t));
|
||||
}
|
||||
|
||||
/* Lookup a symbol in the symbol table. The PREV and NEXT fields of
|
||||
* symbol form the key for the lookup.
|
||||
*
|
||||
* If succesful, then this function returns TRUE and slot_ret will be
|
||||
* left pointing at the result that will have the CODE field of
|
||||
* interest.
|
||||
*
|
||||
* If the lookup fails, then this function returns FALSE and slot_ret
|
||||
* will be pointing at the location in the table to which a new CODE
|
||||
* value should be stored along with PREV and NEXT.
|
||||
*/
|
||||
static cairo_bool_t
|
||||
_lzw_symbol_table_lookup (lzw_symbol_table_t *table,
|
||||
lzw_symbol_t symbol,
|
||||
lzw_symbol_t **slot_ret)
|
||||
{
|
||||
/* The algorithm here is identical to that in cairo-hash.c. We
|
||||
* copy it here to allow for a rather more efficient
|
||||
* implementation due to several circumstances that do not apply
|
||||
* to the more general case:
|
||||
*
|
||||
* 1) We have a known bound on the total number of symbols, so we
|
||||
* have a fixed-size table without any copying when growing
|
||||
*
|
||||
* 2) We never delete any entries, so we don't need to
|
||||
* support/check for DEAD entries during lookup.
|
||||
*
|
||||
* 3) The object fits in 32 bits so we store each object in its
|
||||
* entirety within the table rather than storing objects
|
||||
* externally and putting pointers in the table, (which here
|
||||
* would just double the storage requirements and have negative
|
||||
* impacts on memory locality).
|
||||
*/
|
||||
int i, idx, step, hash = symbol & LZW_SYMBOL_KEY_MASK;
|
||||
lzw_symbol_t candidate;
|
||||
|
||||
idx = hash % LZW_SYMBOL_MOD1;
|
||||
step = 0;
|
||||
|
||||
*slot_ret = NULL;
|
||||
for (i = 0; i < LZW_SYMBOL_TABLE_SIZE; i++)
|
||||
{
|
||||
candidate = table->table[idx];
|
||||
if (candidate == LZW_SYMBOL_FREE)
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return FALSE;
|
||||
}
|
||||
else /* candidate is LIVE */
|
||||
{
|
||||
if ((candidate & LZW_SYMBOL_KEY_MASK) ==
|
||||
(symbol & LZW_SYMBOL_KEY_MASK))
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
step = hash % LZW_SYMBOL_MOD2;
|
||||
if (step == 0)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
idx += step;
|
||||
if (idx >= LZW_SYMBOL_TABLE_SIZE)
|
||||
idx -= LZW_SYMBOL_TABLE_SIZE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Compress a bytestream using the LZW algorithm.
|
||||
*
|
||||
* This is an original implementation based on reading the
|
||||
* specification of the LZWDecode filter in the PostScript Language
|
||||
* Reference. The free parameters in the LZW algorithm are set to the
|
||||
* values mandated by PostScript, (symbols encoded with widths from 9
|
||||
* to 12 bits).
|
||||
*
|
||||
* This function returns a pointer to a newly allocated buffer holding
|
||||
* the compressed data, or NULL if an out-of-memory situation
|
||||
* occurs.
|
||||
*
|
||||
* Notice that any one of the _lzw_buf functions called here could
|
||||
* trigger an out-of-memory condition. But lzw_buf_t uses cairo's
|
||||
* shutdown-on-error idiom, so it's safe to continue to call into
|
||||
* lzw_buf without having to check for errors, (until a final check at
|
||||
* the end).
|
||||
*/
|
||||
cairo_public unsigned char *
|
||||
_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out)
|
||||
{
|
||||
int bytes_remaining = *size_in_out;
|
||||
lzw_buf_t buf;
|
||||
lzw_symbol_table_t table;
|
||||
lzw_symbol_t symbol, *slot;
|
||||
int code_next = LZW_CODE_FIRST;
|
||||
int code_bits = LZW_BITS_MIN;
|
||||
int prev, next;
|
||||
|
||||
if (*size_in_out == 0)
|
||||
return NULL;
|
||||
|
||||
_lzw_buf_init (&buf, *size_in_out);
|
||||
|
||||
_lzw_symbol_table_init (&table);
|
||||
|
||||
/* The LZW header is a clear table code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits);
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Find the longest existing code in the symbol table that
|
||||
* matches the current input, if any. */
|
||||
prev = *data++;
|
||||
bytes_remaining--;
|
||||
if (bytes_remaining) {
|
||||
do
|
||||
{
|
||||
next = *data++;
|
||||
bytes_remaining--;
|
||||
LZW_SYMBOL_SET (symbol, prev, next);
|
||||
if (_lzw_symbol_table_lookup (&table, symbol, &slot))
|
||||
prev = LZW_SYMBOL_GET_CODE (*slot);
|
||||
} while (bytes_remaining && *slot != LZW_SYMBOL_FREE);
|
||||
if (*slot == LZW_SYMBOL_FREE) {
|
||||
data--;
|
||||
bytes_remaining++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the code into the output. This is either a byte read
|
||||
* directly from the input, or a code from the last successful
|
||||
* lookup. */
|
||||
_lzw_buf_store_bits (&buf, prev, code_bits);
|
||||
|
||||
if (bytes_remaining == 0)
|
||||
break;
|
||||
|
||||
LZW_SYMBOL_SET_CODE (*slot, code_next++, prev, next);
|
||||
|
||||
if (code_next > LZW_BITS_BOUNDARY(code_bits))
|
||||
{
|
||||
code_bits++;
|
||||
if (code_bits > LZW_BITS_MAX) {
|
||||
_lzw_symbol_table_init (&table);
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits - 1);
|
||||
code_bits = LZW_BITS_MIN;
|
||||
code_next = LZW_CODE_FIRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The LZW footer is an end-of-data code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_EOD, code_bits);
|
||||
|
||||
_lzw_buf_store_pending (&buf);
|
||||
|
||||
/* See if we ever ran out of memory while writing to buf. */
|
||||
if (buf.status == CAIRO_STATUS_NO_MEMORY) {
|
||||
*size_in_out = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (buf.status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
*size_in_out = buf.num_data;
|
||||
return buf.data;
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ typedef enum {
|
|||
* fallbacks should never get triggered). So the plan is to
|
||||
* eliminate as many of these as possible. */
|
||||
|
||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH,
|
||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH
|
||||
|
||||
} cairo_command_type_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -557,6 +557,7 @@ _cairo_surface_is_meta (const cairo_surface_t *surface)
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_META,
|
||||
_cairo_meta_surface_create_similar,
|
||||
_cairo_meta_surface_finish,
|
||||
_cairo_meta_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -45,53 +45,88 @@
|
|||
|
||||
struct _cairo_output_stream {
|
||||
cairo_write_func_t write_data;
|
||||
cairo_close_func_t close_func;
|
||||
void *closure;
|
||||
cairo_bool_t owns_closure_is_file;
|
||||
unsigned long position;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t closed;
|
||||
};
|
||||
|
||||
const cairo_output_stream_t cairo_output_stream_nil = {
|
||||
NULL, /* write_data */
|
||||
NULL, /* close_func */
|
||||
NULL, /* closure */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_NO_MEMORY,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
static const cairo_output_stream_t cairo_output_stream_nil_write_error = {
|
||||
NULL, /* write_data */
|
||||
NULL, /* close_func */
|
||||
NULL, /* closure */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_WRITE_ERROR,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_data,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure)
|
||||
{
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_output_stream_t));
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
|
||||
stream->write_data = write_data;
|
||||
stream->close_func = close_func;
|
||||
stream->closure = closure;
|
||||
stream->owns_closure_is_file = FALSE;
|
||||
stream->position = 0;
|
||||
stream->status = CAIRO_STATUS_SUCCESS;
|
||||
stream->closed = FALSE;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (stream->closed)
|
||||
return;
|
||||
|
||||
if (stream->close_func) {
|
||||
status = stream->close_func (stream->closure);
|
||||
if (status)
|
||||
stream->status = status;
|
||||
}
|
||||
|
||||
stream->closed = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream)
|
||||
{
|
||||
if (stream->owns_closure_is_file) {
|
||||
FILE *file = stream->closure;
|
||||
fflush (file);
|
||||
fclose (file);
|
||||
}
|
||||
_cairo_output_stream_close (stream);
|
||||
free (stream);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
stream->status = stream->write_data (stream->closure, data, length);
|
||||
stream->position += length;
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -103,6 +138,9 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
|||
char buffer[2];
|
||||
int i, column;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
for (i = 0, column = 0; i < length; i++, column++) {
|
||||
if (column == 38) {
|
||||
_cairo_output_stream_write (stream, "\n", 1);
|
||||
|
|
@ -175,8 +213,7 @@ enum {
|
|||
* formatting. This functionality is only for internal use and we
|
||||
* only implement the formats we actually use.
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
|
|
@ -185,6 +222,9 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
|||
const char *f;
|
||||
int length_modifier;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
f = fmt;
|
||||
p = buffer;
|
||||
while (*f != '\0') {
|
||||
|
|
@ -247,24 +287,19 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
|||
}
|
||||
|
||||
_cairo_output_stream_write (stream, buffer, p - buffer);
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
cairo_status_t status;
|
||||
|
||||
va_start (ap, fmt);
|
||||
|
||||
status = _cairo_output_stream_vprintf (stream, fmt, ap);
|
||||
_cairo_output_stream_vprintf (stream, fmt, ap);
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
long
|
||||
|
|
@ -286,28 +321,33 @@ _cairo_output_stream_get_status (cairo_output_stream_t *stream)
|
|||
static cairo_status_t
|
||||
stdio_write (void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
FILE *fp = closure;
|
||||
FILE *file = closure;
|
||||
|
||||
if (fwrite (data, 1, length, fp) == length)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
if (fwrite (data, 1, length, file) != length)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_close (void *closure)
|
||||
{
|
||||
FILE *file = closure;
|
||||
|
||||
fflush (file);
|
||||
fclose (file);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
cairo_output_stream_t *stream;
|
||||
FILE *file;
|
||||
|
||||
fp = fopen (filename, "wb");
|
||||
if (fp == NULL)
|
||||
return NULL;
|
||||
file = fopen (filename, "wb");
|
||||
if (file == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
|
||||
|
||||
stream = _cairo_output_stream_create (stdio_write, fp);
|
||||
if (stream == NULL)
|
||||
fclose (fp);
|
||||
stream->owns_closure_is_file = TRUE;
|
||||
|
||||
return stream;
|
||||
return _cairo_output_stream_create (stdio_write, stdio_close, file);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,24 @@ const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
|||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface);
|
||||
|
||||
/* XXX: This would seem the natural thing to do here. But currently,
|
||||
* PDF and PS surfaces do not yet work as source surfaces. So instead,
|
||||
* we don't implement create_similar for the paginate_surface which
|
||||
* means that any create_similar() call on a paginated_surfacae will
|
||||
* result in a new image surface. */
|
||||
#if 0
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
return cairo_surface_create_similar (surface->target, content,
|
||||
width, height);
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
|
|
@ -117,6 +135,10 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
|||
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend);
|
||||
|
||||
/* Override surface->base.type with target's type so we don't leak
|
||||
* evidence of the paginated wrapper out to the user. */
|
||||
surface->base.type = cairo_surface_get_type (target);
|
||||
|
||||
surface->content = content;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
|
@ -412,7 +434,8 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
|||
}
|
||||
|
||||
const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
NULL, /* create_similar */
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
NULL, /* create_similar --- see note for _cairo_paginated_surface_create_similar */
|
||||
_cairo_paginated_surface_finish,
|
||||
_cairo_paginated_surface_acquire_source_image,
|
||||
_cairo_paginated_surface_release_source_image,
|
||||
|
|
|
|||
|
|
@ -524,6 +524,18 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
|
|||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_get_type:
|
||||
* @pattern: a #cairo_pattern_t
|
||||
*
|
||||
* Return value: The type of @pattern. See #cairo_pattern_type_t.
|
||||
**/
|
||||
cairo_pattern_type_t
|
||||
cairo_pattern_get_type (cairo_pattern_t *pattern)
|
||||
{
|
||||
return pattern->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_pattern_status:
|
||||
* @pattern: a #cairo_pattern_t
|
||||
|
|
|
|||
|
|
@ -340,11 +340,13 @@ cairo_pdf_surface_create_for_stream (cairo_write_func_t write,
|
|||
double width_in_points,
|
||||
double height_in_points)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create (write, closure);
|
||||
if (stream == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
stream = _cairo_output_stream_create (write, NULL, closure);
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
|
@ -375,11 +377,13 @@ cairo_pdf_surface_create (const char *filename,
|
|||
double width_in_points,
|
||||
double height_in_points)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create_for_file (filename);
|
||||
if (stream == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
|
@ -663,8 +667,10 @@ emit_image_rgb_data (cairo_pdf_document_t *document,
|
|||
opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
||||
image->width,
|
||||
image->height);
|
||||
if (opaque->status)
|
||||
if (opaque->status) {
|
||||
free (rgb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
|
||||
|
||||
|
|
@ -1666,6 +1672,7 @@ _cairo_pdf_surface_get_font_options (void *abstract_surface,
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_PDF,
|
||||
_cairo_pdf_surface_create_similar,
|
||||
_cairo_pdf_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@
|
|||
*
|
||||
* - Add document structure convention comments where appropriate.
|
||||
*
|
||||
* - Fix image compression.
|
||||
*
|
||||
* - Create a set of procs to use... specifically a trapezoid proc.
|
||||
*/
|
||||
|
||||
|
|
@ -108,11 +106,9 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
|
|||
surface->width,
|
||||
surface->height);
|
||||
|
||||
/* The "/FlateDecode filter" currently used is a feature of
|
||||
* LanguageLevel 3 */
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%%%DocumentData: Binary\n"
|
||||
"%%%%LanguageLevel: 3\n"
|
||||
"%%%%DocumentData: Clean7Bit\n"
|
||||
"%%%%LanguageLevel: 2\n"
|
||||
"%%%%Orientation: Portrait\n"
|
||||
"%%%%EndComments\n");
|
||||
}
|
||||
|
|
@ -191,11 +187,13 @@ cairo_ps_surface_create (const char *filename,
|
|||
double width_in_points,
|
||||
double height_in_points)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create_for_file (filename);
|
||||
if (stream == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
|
@ -229,11 +227,13 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
double width_in_points,
|
||||
double height_in_points)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create (write_func, closure);
|
||||
if (stream == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
stream = _cairo_output_stream_create (write_func, NULL, closure);
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
|
@ -665,26 +665,107 @@ pattern_operation_analyze (cairo_operator_t op,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* The "standard" implementation limit for PostScript string sizes is
|
||||
* 65535 characters (see PostScript Language Reference, Appendix
|
||||
* B). We go one short of that because we sometimes need two
|
||||
* characters in a string to represent a single ASCII85 byte, (for the
|
||||
* escape sequences "\\", "\(", and "\)") and we must not split these
|
||||
* across two strings. So we'd be in trouble if we went right to the
|
||||
* limit and one of these escape sequences just happened to land at
|
||||
* the end.
|
||||
*/
|
||||
#define STRING_ARRAY_MAX_STRING_SIZE (65535-1)
|
||||
#define STRING_ARRAY_MAX_COLUMN 72
|
||||
|
||||
typedef struct _string_array_stream {
|
||||
cairo_output_stream_t *output;
|
||||
int column;
|
||||
int string_size;
|
||||
} string_array_stream_t;
|
||||
|
||||
static cairo_status_t
|
||||
_string_array_stream_write (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
string_array_stream_t *stream = closure;
|
||||
unsigned char c;
|
||||
const unsigned char backslash = '\\';
|
||||
|
||||
if (length == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
while (length--) {
|
||||
if (stream->string_size == 0) {
|
||||
_cairo_output_stream_printf (stream->output, "(");
|
||||
stream->column++;
|
||||
}
|
||||
|
||||
c = *data++;
|
||||
switch (c) {
|
||||
case '\\':
|
||||
case '(':
|
||||
case ')':
|
||||
_cairo_output_stream_write (stream->output, &backslash, 1);
|
||||
stream->column++;
|
||||
stream->string_size++;
|
||||
break;
|
||||
}
|
||||
_cairo_output_stream_write (stream->output, &c, 1);
|
||||
stream->column++;
|
||||
stream->string_size++;
|
||||
|
||||
if (stream->string_size >= STRING_ARRAY_MAX_STRING_SIZE) {
|
||||
_cairo_output_stream_printf (stream->output, ")\n");
|
||||
stream->string_size = 0;
|
||||
stream->column = 0;
|
||||
}
|
||||
if (stream->column >= STRING_ARRAY_MAX_COLUMN) {
|
||||
_cairo_output_stream_printf (stream->output, "\n ");
|
||||
stream->string_size += 2;
|
||||
stream->column = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_string_array_stream_close (void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
string_array_stream_t *stream = closure;
|
||||
|
||||
_cairo_output_stream_printf (stream->output, ")\n");
|
||||
|
||||
status = _cairo_output_stream_get_status (stream->output);
|
||||
|
||||
free (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_output_stream_t *
|
||||
_string_array_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
string_array_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (string_array_stream_t));
|
||||
if (stream == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
|
||||
stream->output = output;
|
||||
stream->column = 0;
|
||||
stream->string_size = 0;
|
||||
|
||||
return _cairo_output_stream_create (_string_array_stream_write,
|
||||
_string_array_stream_close,
|
||||
stream);
|
||||
}
|
||||
|
||||
/* PS Output - this section handles output of the parts of the meta
|
||||
* surface we can render natively in PS. */
|
||||
|
||||
static void *
|
||||
compress_dup (const void *data, unsigned long data_size,
|
||||
unsigned long *compressed_size)
|
||||
{
|
||||
void *compressed;
|
||||
|
||||
/* Bound calculation taken from zlib. */
|
||||
*compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
|
||||
compressed = malloc (*compressed_size);
|
||||
if (compressed == NULL)
|
||||
return NULL;
|
||||
|
||||
compress (compressed, compressed_size, data, data_size);
|
||||
|
||||
return compressed;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
emit_image (cairo_ps_surface_t *surface,
|
||||
cairo_image_surface_t *image,
|
||||
|
|
@ -699,6 +780,7 @@ emit_image (cairo_ps_surface_t *surface,
|
|||
cairo_pattern_union_t pattern;
|
||||
cairo_matrix_t d2i;
|
||||
int x, y, i;
|
||||
cairo_output_stream_t *base85_stream, *string_array_stream;
|
||||
|
||||
/* PostScript can not represent the alpha channel, so we blend the
|
||||
current image over a white RGB surface to eliminate it. */
|
||||
|
|
@ -756,56 +838,64 @@ emit_image (cairo_ps_surface_t *surface,
|
|||
}
|
||||
}
|
||||
|
||||
compressed = compress_dup (rgb, rgb_size, &compressed_size);
|
||||
/* XXX: Should fix cairo-lzw to provide a stream-based interface
|
||||
* instead. */
|
||||
compressed_size = rgb_size;
|
||||
compressed = _cairo_lzw_compress (rgb, &compressed_size);
|
||||
if (compressed == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
/* First emit the image data as a base85-encoded string which will
|
||||
* be used as the data source for the image operator later. */
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/%sData [\n", name);
|
||||
|
||||
string_array_stream = _string_array_stream_create (surface->stream);
|
||||
base85_stream = _cairo_base85_stream_create (string_array_stream);
|
||||
|
||||
_cairo_output_stream_write (base85_stream, compressed, compressed_size);
|
||||
|
||||
_cairo_output_stream_destroy (base85_stream);
|
||||
_cairo_output_stream_destroy (string_array_stream);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"] def\n");
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/%sDataIndex 0 def\n", name);
|
||||
|
||||
/* matrix transforms from user space to image space. We need to
|
||||
* transform from device space to image space to compensate for
|
||||
* postscripts coordinate system. */
|
||||
cairo_matrix_init (&d2i, 1, 0, 0, 1, 0, 0);
|
||||
cairo_matrix_multiply (&d2i, &d2i, matrix);
|
||||
|
||||
#if 1
|
||||
/* Construct a string holding the entire image (!) */
|
||||
_cairo_output_stream_printf (surface->stream, "/%sString %d string def\n",
|
||||
name, (int) rgb_size);
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"currentfile %sString readstring\n", name);
|
||||
#else
|
||||
/* Construct a reusable stream decoder holding the image */
|
||||
_cairo_output_stream_printf (surface->stream, "/%sString <<\n", name);
|
||||
/* intent = image data */
|
||||
_cairo_output_stream_printf (surface->stream, "\t/Intent 0\n");
|
||||
#endif
|
||||
/* Compressed image data */
|
||||
_cairo_output_stream_write (surface->stream, rgb, rgb_size);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"\n");
|
||||
|
||||
_cairo_output_stream_printf (surface->stream, "/%s {\n", name);
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/DeviceRGB setcolorspace\n"
|
||||
"<<\n"
|
||||
"/%s {\n"
|
||||
" /DeviceRGB setcolorspace\n"
|
||||
" <<\n"
|
||||
" /ImageType 1\n"
|
||||
" /Width %d\n"
|
||||
" /Height %d\n"
|
||||
" /BitsPerComponent 8\n"
|
||||
" /Decode [ 0 1 0 1 0 1 ]\n"
|
||||
" /DataSource %sString\n"
|
||||
" /DataSource {\n"
|
||||
" %sData %sDataIndex get\n"
|
||||
" /%sDataIndex %sDataIndex 1 add def\n"
|
||||
" %sDataIndex %sData length 1 sub gt { /%sDataIndex 0 def } if\n"
|
||||
" } /ASCII85Decode filter /LZWDecode filter\n"
|
||||
" /ImageMatrix [ %f %f %f %f %f %f ]\n"
|
||||
">>\n"
|
||||
"image\n",
|
||||
" >>\n"
|
||||
" image\n"
|
||||
"} def\n",
|
||||
name,
|
||||
opaque_image->width,
|
||||
opaque_image->height,
|
||||
name,
|
||||
name, name, name, name, name, name, name,
|
||||
d2i.xx, d2i.yx,
|
||||
d2i.xy, d2i.yy,
|
||||
d2i.x0, d2i.y0);
|
||||
_cairo_output_stream_printf (surface->stream, "} bind def\n");
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
@ -862,17 +952,18 @@ emit_surface_pattern (cairo_ps_surface_t *surface,
|
|||
image_extra);
|
||||
}
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"<< /PatternType 1 /PaintType 1 /TilingType 1\n");
|
||||
"<< /PatternType 1\n"
|
||||
" /PaintType 1\n"
|
||||
" /TilingType 1\n");
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/BBox [0 0 %d %d]\n",
|
||||
" /BBox [0 0 %d %d]\n",
|
||||
extents.width, extents.height);
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/XStep %d /YStep %d\n",
|
||||
" /XStep %d /YStep %d\n",
|
||||
extents.width, extents.height);
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"/PaintProc { begin MyPattern\n");
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
" end } bind >> matrix makepattern setpattern\n");
|
||||
" /PaintProc { MyPattern } bind\n"
|
||||
">> matrix makepattern setpattern\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1375,6 +1466,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_PS,
|
||||
NULL, /* create_similar */
|
||||
_cairo_ps_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
|
|
|
|||
|
|
@ -73,10 +73,11 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
|
|||
UInt32 imageDataSize, rowBytes;
|
||||
CGDataProviderRef dataProvider;
|
||||
|
||||
// We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
|
||||
// struct. If the window is ever drawn to without going through Cairo, then
|
||||
// we would need to refetch the pixel data from the window into the cached
|
||||
// image surface.
|
||||
/* We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
|
||||
* struct. If the window is ever drawn to without going through Cairo, then
|
||||
* we would need to refetch the pixel data from the window into the cached
|
||||
* image surface.
|
||||
*/
|
||||
if (surface->image) {
|
||||
cairo_surface_reference(&surface->image->base);
|
||||
|
||||
|
|
@ -257,7 +258,7 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
|||
surface->clip_region = NULL;
|
||||
surface->flipped = flipped;
|
||||
|
||||
// Set up the image surface which Cairo draws into and we blit to & from.
|
||||
/* Set up the image surface which Cairo draws into and we blit to & from. */
|
||||
void *foo;
|
||||
_cairo_quartz_surface_acquire_source_image(surface, &surface->image, &foo);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@
|
|||
#include "cairoint.h"
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_glyph_keys_equal (void *abstract_key_a, void *abstract_key_b)
|
||||
_cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
|
||||
{
|
||||
cairo_scaled_glyph_t *key_a = abstract_key_a;
|
||||
cairo_scaled_glyph_t *key_b = abstract_key_b;
|
||||
const cairo_scaled_glyph_t *key_a = abstract_key_a;
|
||||
const cairo_scaled_glyph_t *key_b = abstract_key_b;
|
||||
|
||||
return (_cairo_scaled_glyph_index (key_a) ==
|
||||
_cairo_scaled_glyph_index (key_b));
|
||||
|
|
@ -118,6 +118,18 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
|
|||
_cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_get_type:
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
*
|
||||
* Return value: The type of @scaled_font. See #cairo_font_type_t.
|
||||
**/
|
||||
cairo_font_type_t
|
||||
cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
return scaled_font->backend->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_scaled_font_status:
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
|
|
@ -168,7 +180,7 @@ static cairo_scaled_font_map_t *cairo_scaled_font_map = NULL;
|
|||
CAIRO_MUTEX_DECLARE (cairo_scaled_font_map_mutex);
|
||||
|
||||
static int
|
||||
_cairo_scaled_font_keys_equal (void *abstract_key_a, void *abstract_key_b);
|
||||
_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b);
|
||||
|
||||
static cairo_scaled_font_map_t *
|
||||
_cairo_scaled_font_map_lock (void)
|
||||
|
|
@ -286,10 +298,10 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_font_keys_equal (void *abstract_key_a, void *abstract_key_b)
|
||||
_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
|
||||
{
|
||||
cairo_scaled_font_t *key_a = abstract_key_a;
|
||||
cairo_scaled_font_t *key_b = abstract_key_b;
|
||||
const cairo_scaled_font_t *key_a = abstract_key_a;
|
||||
const cairo_scaled_font_t *key_b = abstract_key_b;
|
||||
|
||||
return (key_a->font_face == key_b->font_face &&
|
||||
memcmp ((unsigned char *)(&key_a->font_matrix.xx),
|
||||
|
|
|
|||
|
|
@ -549,6 +549,9 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
|
|||
return status;
|
||||
|
||||
clear_region = _cairo_region_create_from_rectangle (&extents);
|
||||
if (clear_region == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _cairo_clip_intersect_to_region (clip, clear_region);
|
||||
if (status)
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
const cairo_surface_t _cairo_surface_nil = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
FALSE, /* finished */
|
||||
|
|
@ -59,6 +60,7 @@ const cairo_surface_t _cairo_surface_nil = {
|
|||
|
||||
const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
|
||||
FALSE, /* finished */
|
||||
|
|
@ -75,6 +77,7 @@ const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
|||
|
||||
const cairo_surface_t _cairo_surface_nil_read_error = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_READ_ERROR, /* status */
|
||||
FALSE, /* finished */
|
||||
|
|
@ -118,6 +121,22 @@ _cairo_surface_set_error (cairo_surface_t *surface,
|
|||
_cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_get_type:
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Return value: The type of @surface. See #cairo_surface_type_t.
|
||||
**/
|
||||
cairo_surface_type_t
|
||||
cairo_surface_get_type (cairo_surface_t *surface)
|
||||
{
|
||||
/* We don't use surface->backend->type here so that some of the
|
||||
* special "wrapper" surfaces such as cairo_paginated_surface_t
|
||||
* can override surface->type with the type of the "child"
|
||||
* surface. */
|
||||
return surface->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_status:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
|
@ -141,6 +160,8 @@ _cairo_surface_init (cairo_surface_t *surface,
|
|||
const cairo_surface_backend_t *backend)
|
||||
{
|
||||
surface->backend = backend;
|
||||
|
||||
surface->type = backend->type;
|
||||
|
||||
surface->ref_count = 1;
|
||||
surface->status = CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -503,6 +524,10 @@ cairo_surface_mark_dirty (cairo_surface_t *surface)
|
|||
* Like cairo_surface_mark_dirty(), but drawing has been done only to
|
||||
* the specified rectangle, so that cairo can retain cached contents
|
||||
* for other parts of the surface.
|
||||
*
|
||||
* Any cached clip set on the surface will be reset by this function,
|
||||
* to make sure that future cairo calls have the clip set that they
|
||||
* expect.
|
||||
*/
|
||||
void
|
||||
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
|
|
@ -521,6 +546,13 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Always reset the clip here, to avoid having external calls to
|
||||
* clip manipulation functions of the underlying device clip result
|
||||
* in a desync between the cairo clip and the backend clip, due to
|
||||
* the clip caching.
|
||||
*/
|
||||
surface->current_clip_serial = -1;
|
||||
|
||||
if (surface->backend->mark_dirty_rectangle) {
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -1330,6 +1362,12 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
|||
if (!surface)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
|
||||
if (clip) {
|
||||
serial = clip->serial;
|
||||
if (serial == 0)
|
||||
|
|
@ -1337,7 +1375,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
|||
}
|
||||
|
||||
surface->clip = clip;
|
||||
|
||||
|
||||
if (serial == _cairo_surface_get_current_clip_serial (surface))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,12 @@ struct cairo_svg_surface {
|
|||
cairo_svg_document_t *document;
|
||||
|
||||
xmlNodePtr xml_node;
|
||||
xmlNodePtr xml_root_node;
|
||||
|
||||
unsigned int clip_level;
|
||||
|
||||
cairo_bool_t modified;
|
||||
unsigned int previous_id;
|
||||
};
|
||||
|
||||
static cairo_svg_document_t *
|
||||
|
|
@ -139,11 +143,15 @@ cairo_svg_surface_create_for_stream (cairo_write_func_t write,
|
|||
double width,
|
||||
double height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create (write, closure);
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
stream = _cairo_output_stream_create (write, NULL, closure);
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t *) &cairo_surface_nil;
|
||||
}
|
||||
|
||||
return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
|
||||
}
|
||||
|
|
@ -153,11 +161,15 @@ cairo_svg_surface_create (const char *filename,
|
|||
double width,
|
||||
double height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = _cairo_output_stream_create_for_file (filename);
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
status = _cairo_output_stream_get_status (stream);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t *) &cairo_surface_nil;
|
||||
}
|
||||
|
||||
return _cairo_svg_surface_create_for_stream_internal (stream, width, height);
|
||||
}
|
||||
|
|
@ -209,15 +221,16 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
|||
_cairo_dtostr (buffer, sizeof buffer, height);
|
||||
xmlSetProp (clip_rect, CC2XML ("height"), C2XML (buffer));
|
||||
|
||||
surface->xml_node = xmlNewChild (surface->id == 0 ?
|
||||
document->xml_node_main :
|
||||
document->xml_node_defs,
|
||||
NULL, CC2XML ("g"), NULL);
|
||||
surface->xml_node = xmlNewNode (NULL, CC2XML ("g"));
|
||||
surface->xml_root_node = surface->xml_node;
|
||||
|
||||
snprintf (buffer, sizeof buffer, "surface%d", surface->id);
|
||||
xmlSetProp (surface->xml_node, CC2XML ("id"), C2XML (buffer));
|
||||
snprintf (buffer, sizeof buffer, "url(#clip%d)", clip_id);
|
||||
xmlSetProp (surface->xml_node, CC2XML ("clip-path"), C2XML (buffer));
|
||||
|
||||
surface->modified = TRUE;
|
||||
surface->previous_id = surface->id;
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
|
@ -240,14 +253,19 @@ _cairo_svg_surface_finish (void *abstract_surface)
|
|||
cairo_status_t status;
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
cairo_svg_document_t *document = surface->document;
|
||||
|
||||
|
||||
if (document->owner == &surface->base)
|
||||
if (document->owner == &surface->base) {
|
||||
xmlAddChild (document->xml_node_main, xmlCopyNode (surface->xml_root_node, 1));
|
||||
status = _cairo_svg_document_finish (document);
|
||||
else
|
||||
} else
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_svg_document_destroy (document);
|
||||
|
||||
xmlFreeNode (surface->xml_root_node);
|
||||
surface->xml_node = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -263,22 +281,22 @@ emit_transform (xmlNodePtr node,
|
|||
xmlBufferCat (matrix_buffer, CC2XML ("matrix("));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->xx);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ",");
|
||||
xmlBufferCat (matrix_buffer, CC2XML (","));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->yx);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ",");
|
||||
xmlBufferCat (matrix_buffer, CC2XML (","));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->xy);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ",");
|
||||
xmlBufferCat (matrix_buffer, CC2XML (","));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->yy);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ",");
|
||||
xmlBufferCat (matrix_buffer, CC2XML (","));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->x0);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ",");
|
||||
xmlBufferCat (matrix_buffer, CC2XML(","));
|
||||
_cairo_dtostr (buffer, sizeof buffer, matrix->y0);
|
||||
xmlBufferCat (matrix_buffer, C2XML (buffer));
|
||||
xmlBufferCat (matrix_buffer, ")");
|
||||
xmlBufferCat (matrix_buffer, CC2XML (")"));
|
||||
xmlSetProp (node, CC2XML (attribute_str), C2XML (xmlBufferContent (matrix_buffer)));
|
||||
xmlBufferFree (matrix_buffer);
|
||||
}
|
||||
|
|
@ -292,7 +310,7 @@ typedef struct {
|
|||
unsigned int trailing;
|
||||
} base64_write_closure_t;
|
||||
|
||||
static unsigned char const *base64_table =
|
||||
static char const *base64_table =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -325,7 +343,7 @@ base64_write_func (void *closure,
|
|||
info->count++;
|
||||
if (info->count >= 18) {
|
||||
info->count = 0;
|
||||
xmlBufferCat (info->buffer, "\r\n");
|
||||
xmlBufferCat (info->buffer, CC2XML ("\r\n"));
|
||||
}
|
||||
dst[0] = base64_table[src[0] >> 2];
|
||||
dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
|
||||
|
|
@ -450,16 +468,16 @@ emit_composite_svg_pattern (xmlNodePtr node,
|
|||
cairo_bool_t is_pattern)
|
||||
{
|
||||
cairo_svg_surface_t *surface = (cairo_svg_surface_t *) pattern->surface;
|
||||
cairo_svg_document_t *document = surface->document;
|
||||
cairo_matrix_t p2u;
|
||||
xmlNodePtr child;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
/* FIXME: self copy is not supported yet */
|
||||
if (surface->id == 0)
|
||||
return NULL;
|
||||
if (surface->modified)
|
||||
xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
|
||||
|
||||
child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
|
||||
snprintf (buffer, sizeof buffer, "#surface%d", surface->id);
|
||||
snprintf (buffer, sizeof buffer, "#surface%d", surface->previous_id);
|
||||
xmlSetProp (child, CC2XML ("xlink:href"), C2XML (buffer));
|
||||
|
||||
if (!is_pattern) {
|
||||
|
|
@ -473,6 +491,14 @@ emit_composite_svg_pattern (xmlNodePtr node,
|
|||
if (height != NULL)
|
||||
*height = surface->height;
|
||||
|
||||
if (surface->modified) {
|
||||
surface->modified = FALSE;
|
||||
surface->previous_id = surface->id;
|
||||
surface->id = document->surface_id++;
|
||||
snprintf (buffer, sizeof buffer, "surface%d", surface->id);
|
||||
xmlSetProp (surface->xml_root_node, CC2XML ("id"), C2XML (buffer));
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
|
@ -762,19 +788,19 @@ emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,
|
|||
xmlBufferPtr style, int is_stroke)
|
||||
{
|
||||
switch (pattern->type) {
|
||||
case CAIRO_PATTERN_SOLID:
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, style, is_stroke);
|
||||
break;
|
||||
|
||||
case CAIRO_PATTERN_SURFACE:
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, style, is_stroke);
|
||||
break;
|
||||
|
||||
case CAIRO_PATTERN_LINEAR:
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, style, is_stroke);
|
||||
break;
|
||||
|
||||
case CAIRO_PATTERN_RADIAL:
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, style, is_stroke);
|
||||
break;
|
||||
}
|
||||
|
|
@ -898,9 +924,9 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
|
||||
style = xmlBufferCreate ();
|
||||
emit_pattern (surface, source, style, 0);
|
||||
xmlBufferCat (style, " stroke: none;");
|
||||
xmlBufferCat (style, " fill-rule: ");
|
||||
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? "evenodd;" : "nonzero;");
|
||||
xmlBufferCat (style, CC2XML (" stroke: none;"));
|
||||
xmlBufferCat (style, CC2XML (" fill-rule: "));
|
||||
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? CC2XML("evenodd;") : CC2XML ("nonzero;"));
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
|
|
@ -918,6 +944,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
xmlBufferFree (info.path);
|
||||
xmlBufferFree (style);
|
||||
|
||||
surface->modified = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -950,14 +977,14 @@ emit_paint (xmlNodePtr node,
|
|||
xmlBufferPtr style;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (source->type == CAIRO_PATTERN_SURFACE)
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
|
||||
return emit_composite_pattern (node,
|
||||
(cairo_surface_pattern_t *) source,
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
style = xmlBufferCreate ();
|
||||
emit_pattern (surface, source, style, 0);
|
||||
xmlBufferCat (style, " stroke: none;");
|
||||
xmlBufferCat (style, CC2XML (" stroke: none;"));
|
||||
|
||||
child = xmlNewChild (node, NULL, CC2XML ("rect"), NULL);
|
||||
xmlSetProp (child, CC2XML ("x"), CC2XML ("0"));
|
||||
|
|
@ -980,8 +1007,10 @@ _cairo_svg_surface_paint (void *abstract_surface,
|
|||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
|
||||
|
||||
emit_paint (surface->xml_node, surface, op, source);
|
||||
|
||||
surface->modified = TRUE;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1010,6 +1039,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
|
|||
|
||||
document->mask_id++;
|
||||
|
||||
surface->modified = TRUE;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1076,21 +1106,21 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
|||
xmlBufferCat (style, CC2XML (" stroke-dasharray: "));
|
||||
for (i = 0; i < stroke_style->num_dashes; i++) {
|
||||
if (i != 0)
|
||||
xmlBufferCat (style, ",");
|
||||
xmlBufferCat (style, CC2XML (","));
|
||||
/* FIXME: Is is really what we want ? */
|
||||
rx = ry = stroke_style->dash[i];
|
||||
cairo_matrix_transform_distance (ctm, &rx, &ry);
|
||||
_cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
|
||||
xmlBufferCat (style, C2XML (buffer));
|
||||
}
|
||||
xmlBufferCat (style, ";");
|
||||
xmlBufferCat (style, CC2XML (";"));
|
||||
if (stroke_style->dash_offset != 0.0) {
|
||||
xmlBufferCat (style, CC2XML (" stroke-dashoffset: "));
|
||||
rx = ry = stroke_style->dash_offset;
|
||||
cairo_matrix_transform_distance (ctm, &rx, &ry);
|
||||
_cairo_dtostr (buffer, sizeof buffer, sqrt ((rx * rx + ry * ry) / 2.0));
|
||||
xmlBufferCat (style, C2XML (buffer));
|
||||
xmlBufferCat (style, ";");
|
||||
xmlBufferCat (style, CC2XML (";"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1115,6 +1145,7 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
|||
xmlBufferFree (info.path);
|
||||
xmlBufferFree (style);
|
||||
|
||||
surface->modified = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -1126,6 +1157,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
|||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
cairo_path_fixed_t path;
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -1149,6 +1181,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
|||
|
||||
_cairo_path_fixed_fini (&path);
|
||||
|
||||
surface->modified = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -1167,10 +1200,8 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
|
|||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (path == NULL) {
|
||||
while (surface->clip_level > 0) {
|
||||
surface->xml_node = surface->xml_node->parent;
|
||||
surface->clip_level--;
|
||||
}
|
||||
surface->xml_node = surface->xml_root_node;
|
||||
surface->clip_level = 0;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1221,6 +1252,7 @@ _cairo_svg_surface_get_font_options (void *abstract_surface,
|
|||
|
||||
|
||||
static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_SVG,
|
||||
_cairo_svg_surface_create_similar,
|
||||
_cairo_svg_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
|
|
@ -1318,21 +1350,34 @@ _cairo_svg_document_destroy (cairo_svg_document_t *document)
|
|||
free (document);
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_svg_document_write (cairo_output_stream_t *output_stream,
|
||||
const char * buffer,
|
||||
int len)
|
||||
{
|
||||
if (_cairo_output_stream_write (output_stream, buffer, len) != CAIRO_STATUS_SUCCESS)
|
||||
return -1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_svg_document_finish (cairo_svg_document_t *document)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_output_stream_t *output = document->output_stream;
|
||||
xmlChar *xml_buffer;
|
||||
int xml_buffer_size;
|
||||
xmlOutputBufferPtr xml_output_buffer;
|
||||
|
||||
if (document->finished)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* FIXME: Dumping xml tree in memory is silly. */
|
||||
xmlDocDumpFormatMemoryEnc (document->xml_doc, &xml_buffer, &xml_buffer_size, "UTF-8", 1);
|
||||
_cairo_output_stream_write (document->output_stream, xml_buffer, xml_buffer_size);
|
||||
xmlFree(xml_buffer);
|
||||
xml_output_buffer = xmlOutputBufferCreateIO ((xmlOutputWriteCallback) _cairo_svg_document_write,
|
||||
(xmlOutputCloseCallback) NULL,
|
||||
(void *) document->output_stream,
|
||||
NULL);
|
||||
xmlSaveFormatFileTo (xml_output_buffer, document->xml_doc, "UTF-8", 1);
|
||||
|
||||
xmlFreeDoc (document->xml_doc);
|
||||
|
||||
status = _cairo_output_stream_get_status (output);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* $Id: cairo-wideint.c,v 1.6 2005-07-30 19:57:54 keithp Exp $
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* $Id: cairo-wideint.h,v 1.12 2005-08-05 14:48:19 cworth Exp $
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1159,7 +1159,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
|||
cairo_surface_pattern_t mask;
|
||||
RECT r;
|
||||
|
||||
tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
|
||||
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;
|
||||
|
||||
|
|
@ -1355,6 +1355,7 @@ CLEANUP_FONT:
|
|||
}
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_WIN32,
|
||||
_cairo_win32_scaled_font_create_toy,
|
||||
_cairo_win32_scaled_font_fini,
|
||||
_cairo_win32_scaled_font_glyph_init,
|
||||
|
|
|
|||
|
|
@ -62,19 +62,14 @@ typedef struct _cairo_win32_surface {
|
|||
|
||||
cairo_rectangle_t clip_rect;
|
||||
|
||||
int set_clip;
|
||||
HRGN saved_clip;
|
||||
|
||||
cairo_rectangle_t extents;
|
||||
} cairo_win32_surface_t;
|
||||
|
||||
cairo_status_t
|
||||
_cairo_win32_print_gdi_error (const char *context);
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_win32_surface_create_dib (cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_win32 (cairo_surface_t *surface);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Stuart Parmenter <stuart@mozilla.com>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -274,9 +276,14 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
|||
surface->clip_rect.width = width;
|
||||
surface->clip_rect.height = height;
|
||||
|
||||
surface->set_clip = 0;
|
||||
surface->saved_clip = NULL;
|
||||
|
||||
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
||||
if (GetClipRgn (surface->dc, surface->saved_clip) == 0) {
|
||||
DeleteObject(surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
|
||||
surface->extents = surface->clip_rect;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
||||
|
||||
return (cairo_surface_t *)surface;
|
||||
|
|
@ -311,27 +318,6 @@ _cairo_win32_surface_create_similar (void *abstract_src,
|
|||
return _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_win32_surface_create_dib:
|
||||
* @format: format of pixels in the surface to create
|
||||
* @width: width of the surface, in pixels
|
||||
* @height: height of the surface, in pixels
|
||||
*
|
||||
* Creates a device-independent-bitmap surface not associated with
|
||||
* any particular existing surface or device context. The created
|
||||
* bitmap will be unititialized.
|
||||
*
|
||||
* Return value: the newly created surface, or %NULL if it couldn't
|
||||
* be created (probably because of lack of memory)
|
||||
**/
|
||||
cairo_surface_t *
|
||||
_cairo_win32_surface_create_dib (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_finish (void *abstract_surface)
|
||||
{
|
||||
|
|
@ -340,9 +326,8 @@ _cairo_win32_surface_finish (void *abstract_surface)
|
|||
if (surface->image)
|
||||
cairo_surface_destroy (surface->image);
|
||||
|
||||
if (surface->saved_clip) {
|
||||
if (surface->saved_clip)
|
||||
DeleteObject (surface->saved_clip);
|
||||
}
|
||||
|
||||
/* If we created the Bitmap and DC, destroy them */
|
||||
if (surface->bitmap) {
|
||||
|
|
@ -379,8 +364,18 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
|
|||
width, height,
|
||||
surface->dc,
|
||||
x, y,
|
||||
SRCCOPY))
|
||||
goto FAIL;
|
||||
SRCCOPY)) {
|
||||
/* If we fail to BitBlt here, most likely the source is a printer.
|
||||
* You can't reliably get bits from a printer DC, so just fill in
|
||||
* the surface as white (common case for printing).
|
||||
*/
|
||||
|
||||
RECT r;
|
||||
r.left = r.top = 0;
|
||||
r.right = width;
|
||||
r.bottom = height;
|
||||
FillRect(local->dc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
}
|
||||
|
||||
*local_out = local;
|
||||
|
||||
|
|
@ -403,7 +398,7 @@ _cairo_win32_surface_acquire_source_image (void *abstract_sur
|
|||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_win32_surface_t *local = NULL;
|
||||
cairo_status_t status;
|
||||
|
||||
|
||||
if (surface->image) {
|
||||
*image_out = (cairo_image_surface_t *)surface->image;
|
||||
*image_extra = NULL;
|
||||
|
|
@ -446,7 +441,7 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
|
|||
cairo_status_t status;
|
||||
RECT clip_box;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
|
||||
if (surface->image) {
|
||||
image_rect->x = 0;
|
||||
image_rect->y = 0;
|
||||
|
|
@ -461,12 +456,12 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
|
|||
|
||||
if (GetClipBox (surface->dc, &clip_box) == ERROR)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
|
||||
|
||||
|
||||
x1 = clip_box.left;
|
||||
x2 = clip_box.right;
|
||||
y1 = clip_box.top;
|
||||
y2 = clip_box.bottom;
|
||||
|
||||
|
||||
if (interest_rect->x > x1)
|
||||
x1 = interest_rect->x;
|
||||
if (interest_rect->y > y1)
|
||||
|
|
@ -595,6 +590,8 @@ _composite_alpha_blend (cairo_win32_surface_t *dst,
|
|||
|
||||
if (alpha_blend == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (GetDeviceCaps(dst->dc, SHADEBLENDCAPS) == SB_NONE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
blend_function.BlendOp = AC_SRC_OVER;
|
||||
blend_function.BlendFlags = 0;
|
||||
|
|
@ -634,7 +631,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
int integer_transform;
|
||||
int itx, ity;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_SURFACE ||
|
||||
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||
|
||||
pattern->extend != CAIRO_EXTEND_NONE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
@ -642,7 +639,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
/* FIXME: When we fully support RENDER style 4-channel
|
||||
* masks we need to check r/g/b != 1.0.
|
||||
*/
|
||||
if (mask_pattern->type != CAIRO_PATTERN_SOLID)
|
||||
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;
|
||||
|
|
@ -660,6 +657,33 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
if (!integer_transform)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Fix up src coordinates; the src coords and size must be within the
|
||||
* bounds of the source surface.
|
||||
* XXX the region not covered should be appropriately rendered!
|
||||
* - for OVER/SOURCE with RGB24 source -> opaque black
|
||||
* - for SOURCE with ARGB32 source -> 100% transparent black
|
||||
*/
|
||||
src_x += itx;
|
||||
src_y += ity;
|
||||
|
||||
if (src_x < 0) {
|
||||
width += src_x;
|
||||
dst_x -= src_x;
|
||||
src_x = 0;
|
||||
}
|
||||
|
||||
if (src_y < 0) {
|
||||
height += src_y;
|
||||
dst_y -= src_y;
|
||||
src_y = 0;
|
||||
}
|
||||
|
||||
if (src_x + width > src->extents.width)
|
||||
width = src->extents.width - src_x;
|
||||
|
||||
if (src_y + height > src->extents.height)
|
||||
height = src->extents.height - src_y;
|
||||
|
||||
if (alpha == 255 &&
|
||||
src->format == dst->format &&
|
||||
(op == CAIRO_OPERATOR_SOURCE ||
|
||||
|
|
@ -669,7 +693,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
dst_x, dst_y,
|
||||
width, height,
|
||||
src->dc,
|
||||
src_x + itx, src_y + ity,
|
||||
src_x, src_y,
|
||||
SRCCOPY))
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
|
||||
|
||||
|
|
@ -681,7 +705,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
op == CAIRO_OPERATOR_OVER) {
|
||||
|
||||
return _composite_alpha_blend (dst, src, alpha,
|
||||
src_x + itx, src_y + ity,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y, width, height);
|
||||
}
|
||||
|
||||
|
|
@ -855,19 +879,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
if (region == NULL) {
|
||||
/* Clear any clip set by cairo, return to the original */
|
||||
|
||||
if (surface->set_clip) {
|
||||
if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
||||
if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
|
||||
|
||||
if (surface->saved_clip) {
|
||||
DeleteObject (surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
|
||||
surface->set_clip = 0;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
} else {
|
||||
|
|
@ -910,36 +924,16 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
if (!gdi_region)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (surface->set_clip) {
|
||||
/* 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;
|
||||
}
|
||||
/* Combine the new region with the original clip */
|
||||
|
||||
if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
||||
if (surface->saved_clip) {
|
||||
if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
|
||||
goto FAIL;
|
||||
|
||||
} else {
|
||||
/* Save the the current region */
|
||||
|
||||
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
||||
if (!surface->saved_clip) {
|
||||
goto FAIL; }
|
||||
|
||||
/* This function has no error return! */
|
||||
if (GetClipRgn (surface->dc, surface->saved_clip) == 0) { /* No clip */
|
||||
DeleteObject (surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
|
||||
if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
|
||||
goto FAIL;
|
||||
|
||||
surface->set_clip = 1;
|
||||
}
|
||||
|
||||
if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
|
||||
goto FAIL;
|
||||
|
||||
DeleteObject (gdi_region);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
@ -955,15 +949,8 @@ _cairo_win32_surface_get_extents (void *abstract_surface,
|
|||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
RECT clip_box;
|
||||
|
||||
if (GetClipBox (surface->dc, &clip_box) == ERROR)
|
||||
return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
|
||||
|
||||
rectangle->x = clip_box.left;
|
||||
rectangle->y = clip_box.top;
|
||||
rectangle->width = clip_box.right - clip_box.left;
|
||||
rectangle->height = clip_box.bottom - clip_box.top;
|
||||
*rectangle = surface->extents;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -974,11 +961,25 @@ _cairo_win32_surface_flush (void *abstract_surface)
|
|||
return _cairo_surface_reset_clip (abstract_surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_win32_surface_create:
|
||||
* @hdc: the DC to create a surface for
|
||||
*
|
||||
* 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
|
||||
* size of the cairo surface. Also, if the DC is a raster DC, it will
|
||||
* be queried for its pixel format and the cairo surface format will
|
||||
* be set appropriately.
|
||||
*
|
||||
* Return value: the newly created surface
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_win32_surface_create (HDC hdc)
|
||||
{
|
||||
cairo_win32_surface_t *surface;
|
||||
RECT rect;
|
||||
int depth;
|
||||
cairo_format_t format;
|
||||
|
||||
/* Try to figure out the drawing bounds for the Device context
|
||||
*/
|
||||
|
|
@ -988,7 +989,28 @@ cairo_win32_surface_create (HDC hdc)
|
|||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
|
||||
if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
|
||||
depth = GetDeviceCaps(hdc, BITSPIXEL);
|
||||
if (depth == 32)
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
else if (depth == 24)
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
else if (depth == 16)
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
else if (depth == 8)
|
||||
format = CAIRO_FORMAT_A8;
|
||||
else if (depth == 1)
|
||||
format = CAIRO_FORMAT_A1;
|
||||
else {
|
||||
_cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return &_cairo_surface_nil;
|
||||
}
|
||||
} else {
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
}
|
||||
|
||||
surface = malloc (sizeof (cairo_win32_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
|
@ -996,7 +1018,7 @@ cairo_win32_surface_create (HDC hdc)
|
|||
}
|
||||
|
||||
surface->image = NULL;
|
||||
surface->format = CAIRO_FORMAT_RGB24;
|
||||
surface->format = format;
|
||||
|
||||
surface->dc = hdc;
|
||||
surface->bitmap = NULL;
|
||||
|
|
@ -1007,14 +1029,47 @@ cairo_win32_surface_create (HDC hdc)
|
|||
surface->clip_rect.width = rect.right - rect.left;
|
||||
surface->clip_rect.height = rect.bottom - rect.top;
|
||||
|
||||
surface->set_clip = 0;
|
||||
surface->saved_clip = NULL;
|
||||
if (surface->clip_rect.width == 0 ||
|
||||
surface->clip_rect.height == 0)
|
||||
{
|
||||
surface->saved_clip = NULL;
|
||||
} else {
|
||||
surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
|
||||
if (GetClipRgn (hdc, surface->saved_clip) == 0) {
|
||||
DeleteObject(surface->saved_clip);
|
||||
surface->saved_clip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
surface->extents = surface->clip_rect;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
||||
|
||||
return (cairo_surface_t *)surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_win32_surface_create_with_dib:
|
||||
* @format: format of pixels in the surface to create
|
||||
* @width: width of the surface, in pixels
|
||||
* @height: height of the surface, in pixels
|
||||
*
|
||||
* Creates a device-independent-bitmap surface not associated with
|
||||
* any particular existing surface or device context. The created
|
||||
* bitmap will be unititialized.
|
||||
*
|
||||
* Return value: the newly created surface
|
||||
*
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_win32_surface_create_with_dib (cairo_format_t format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _cairo_surface_is_win32:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
|
@ -1029,7 +1084,33 @@ _cairo_surface_is_win32 (cairo_surface_t *surface)
|
|||
return surface->backend == &cairo_win32_surface_backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_win32_surface_get_dc
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Returns the HDC associated with this surface, or NULL if none.
|
||||
* Also returns NULL if the surface is not a win32 surface.
|
||||
*
|
||||
* Return value: HDC or NULL if no HDC available.
|
||||
**/
|
||||
HDC
|
||||
cairo_win32_surface_get_dc (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_win32_surface_t *winsurf;
|
||||
|
||||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!_cairo_surface_is_win32(surface))
|
||||
return NULL;
|
||||
|
||||
winsurf = (cairo_win32_surface_t *) surface;
|
||||
|
||||
return winsurf->dc;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_WIN32,
|
||||
_cairo_win32_surface_create_similar,
|
||||
_cairo_win32_surface_finish,
|
||||
_cairo_win32_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ CAIRO_BEGIN_DECLS
|
|||
cairo_public cairo_surface_t *
|
||||
cairo_win32_surface_create (HDC hdc);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_win32_surface_create_with_dib (cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_public HDC
|
||||
cairo_win32_surface_get_dc (cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont);
|
||||
|
||||
|
|
|
|||
|
|
@ -1025,6 +1025,7 @@ _cairo_xcb_surface_get_extents (void *abstract_surface,
|
|||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_XCB,
|
||||
_cairo_xcb_surface_create_similar,
|
||||
_cairo_xcb_surface_finish,
|
||||
_cairo_xcb_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "cairo-xlib-test.h"
|
||||
#include "cairo-xlib-private.h"
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <X11/extensions/renderproto.h>
|
||||
|
||||
/* Xlib doesn't define a typedef, so define one ourselves */
|
||||
typedef int (*cairo_xlib_error_func_t) (Display *display,
|
||||
|
|
@ -1675,6 +1676,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
|
|||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
static const cairo_surface_backend_t cairo_xlib_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_XLIB,
|
||||
_cairo_xlib_surface_create_similar,
|
||||
_cairo_xlib_surface_finish,
|
||||
_cairo_xlib_surface_acquire_source_image,
|
||||
|
|
@ -2403,6 +2405,8 @@ _cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
cairo_int_status_t status;
|
||||
cairo_xlib_surface_t *self = abstract_surface;
|
||||
cairo_xlib_surface_t *src;
|
||||
const cairo_glyph_t *glyphs_chunk;
|
||||
int glyphs_remaining, chunk_size, max_chunk_size;
|
||||
composite_operation_t operation;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
cairo_xlib_surface_font_private_t *font_private;
|
||||
|
|
@ -2457,23 +2461,41 @@ _cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
}
|
||||
|
||||
_cairo_xlib_surface_ensure_dst_picture (self);
|
||||
/* Call the appropriate sub-function. */
|
||||
|
||||
max_chunk_size = XMaxRequestSize (self->dpy);
|
||||
if (max_index < 256)
|
||||
status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
|
||||
else if (max_index < 65536)
|
||||
status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
else
|
||||
status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs, num_glyphs);
|
||||
max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
|
||||
else
|
||||
max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
|
||||
max_chunk_size /= sz_xGlyphElt;
|
||||
|
||||
for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
|
||||
glyphs_remaining;
|
||||
glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
|
||||
{
|
||||
chunk_size = MIN (glyphs_remaining, max_chunk_size);
|
||||
|
||||
/* Call the appropriate sub-function. */
|
||||
if (max_index < 256)
|
||||
status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs_chunk, chunk_size);
|
||||
else if (max_index < 65536)
|
||||
status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs_chunk, chunk_size);
|
||||
else
|
||||
status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
|
||||
source_x + attributes.x_offset - dest_x,
|
||||
source_y + attributes.y_offset - dest_y,
|
||||
glyphs_chunk, chunk_size);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_rectangle_t extents;
|
||||
|
|
|
|||
|
|
@ -2155,6 +2155,9 @@ cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
|
|||
if (cr->status)
|
||||
return;
|
||||
|
||||
if (num_glyphs == 0)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
|
||||
if (cr->status)
|
||||
_cairo_set_error (cr, cr->status);
|
||||
|
|
|
|||
|
|
@ -184,6 +184,10 @@ cairo_private void _cairo_beos_unlock(void*);
|
|||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define ASSERT_NOT_REACHED \
|
||||
do { \
|
||||
static const int NOT_REACHED = 0; \
|
||||
|
|
@ -256,6 +260,15 @@ typedef enum cairo_int_status {
|
|||
CAIRO_INT_STATUS_CACHE_EMPTY
|
||||
} cairo_int_status_t;
|
||||
|
||||
typedef enum cairo_internal_surface_type {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
|
||||
} cairo_internal_surface_type_t;
|
||||
|
||||
typedef enum cairo_direction {
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
CAIRO_DIRECTION_REVERSE
|
||||
|
|
@ -509,6 +522,8 @@ typedef enum _cairo_scaled_glyph_info {
|
|||
} cairo_scaled_glyph_info_t;
|
||||
|
||||
struct _cairo_scaled_font_backend {
|
||||
cairo_font_type_t type;
|
||||
|
||||
cairo_status_t
|
||||
(*create_toy) (cairo_toy_font_face_t *toy_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
|
|
@ -602,6 +617,8 @@ typedef struct _cairo_stroke_style {
|
|||
} cairo_stroke_style_t;
|
||||
|
||||
struct _cairo_surface_backend {
|
||||
cairo_surface_type_t type;
|
||||
|
||||
cairo_surface_t *
|
||||
(*create_similar) (void *surface,
|
||||
cairo_content_t content,
|
||||
|
|
@ -832,6 +849,11 @@ typedef struct _cairo_format_masks {
|
|||
struct _cairo_surface {
|
||||
const cairo_surface_backend_t *backend;
|
||||
|
||||
/* We allow surfaces to override the backend->type by shoving something
|
||||
* else into surface->type. This is for "wrapper" surfaces that want to
|
||||
* hide their internal type from the user-level API. */
|
||||
cairo_surface_type_t type;
|
||||
|
||||
unsigned int ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t finished;
|
||||
|
|
@ -2103,14 +2125,37 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
|||
|
||||
typedef struct _cairo_output_stream cairo_output_stream_t;
|
||||
|
||||
extern const cairo_private cairo_output_stream_t cairo_output_stream_nil;
|
||||
|
||||
/* We already have the following declared in cairo.h:
|
||||
|
||||
typedef cairo_status_t (*cairo_write_func_t) (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
*/
|
||||
typedef cairo_status_t (*cairo_close_func_t) (void *closure);
|
||||
|
||||
|
||||
/* This function never returns NULL. If an error occurs (NO_MEMORY)
|
||||
* while trying to create the output stream this function returns a
|
||||
* valid pointer to a nil output stream.
|
||||
*
|
||||
* Note that even with a nil surface, the close_func callback will be
|
||||
* called by a call to _cairo_output_stream_close or
|
||||
* _cairo_output_stream_destroy.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length);
|
||||
|
||||
|
|
@ -2119,11 +2164,14 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
|||
const char *data,
|
||||
size_t length);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private unsigned char *
|
||||
_cairo_lzw_compress (unsigned char *data, unsigned long *data_size_in_out);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt, va_list ap);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt, ...) CAIRO_PRINTF_FORMAT(2, 3);
|
||||
|
||||
|
|
@ -2133,9 +2181,21 @@ _cairo_output_stream_get_position (cairo_output_stream_t *status);
|
|||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_get_status (cairo_output_stream_t *stream);
|
||||
|
||||
/* This function never returns NULL. If an error occurs (NO_MEMORY or
|
||||
* WRITE_ERROR) while trying to create the output stream this function
|
||||
* returns a valid pointer to a nil output stream.
|
||||
*
|
||||
* NOTE: Even if a nil surface is returned, the caller should still
|
||||
* call _cairo_output_stream_destroy (or _cairo_output_stream_close at
|
||||
* least) in order to ensure that everything is properly cleaned up.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (const char *filename);
|
||||
|
||||
/* cairo_base85_stream.c */
|
||||
cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
cairo_private void
|
||||
_cairo_error (cairo_status_t status);
|
||||
|
||||
|
|
@ -2143,7 +2203,6 @@ cairo_private int
|
|||
_cairo_dtostr (char *buffer, size_t size, double d);
|
||||
|
||||
/* Avoid unnecessary PLT entries. */
|
||||
|
||||
slim_hidden_proto(cairo_get_current_point)
|
||||
slim_hidden_proto(cairo_fill_preserve)
|
||||
slim_hidden_proto(cairo_clip_preserve)
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ _test_fallback_surface_get_extents (void *abstract_surface,
|
|||
}
|
||||
|
||||
const cairo_surface_backend_t test_fallback_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
_test_fallback_surface_create_similar,
|
||||
_test_fallback_surface_finish,
|
||||
_test_fallback_surface_acquire_source_image,
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ _test_meta_surface_snapshot (void *abstract_other)
|
|||
}
|
||||
|
||||
const cairo_surface_backend_t test_meta_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
NULL, /* create_similar */
|
||||
_test_meta_surface_finish,
|
||||
_test_meta_surface_acquire_source_image,
|
||||
|
|
|
|||
3
test/.gitignore
vendored
3
test/.gitignore
vendored
|
|
@ -24,6 +24,7 @@ fill-and-stroke
|
|||
fill-rule
|
||||
filter-nearest-offset
|
||||
ft-font-create-for-ft-face
|
||||
font-face-get-type
|
||||
get-and-set
|
||||
gradient-alpha
|
||||
imagediff
|
||||
|
|
@ -43,6 +44,7 @@ operator-source
|
|||
paint
|
||||
paint-with-alpha
|
||||
path-data
|
||||
pattern-get-type
|
||||
pdf2png
|
||||
png-flatten
|
||||
svg2png
|
||||
|
|
@ -59,6 +61,7 @@ select-font-no-show-text
|
|||
self-copy
|
||||
self-intersecting
|
||||
set-source
|
||||
show-glyphs-many
|
||||
show-text-current-point
|
||||
source-clip
|
||||
source-surface-scale-paint
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ extend-reflect \
|
|||
fill-and-stroke \
|
||||
fill-rule \
|
||||
filter-nearest-offset \
|
||||
font-face-get-type \
|
||||
get-and-set \
|
||||
gradient-alpha \
|
||||
leaky-polygon \
|
||||
|
|
@ -35,6 +36,7 @@ operator-source \
|
|||
paint \
|
||||
paint-with-alpha \
|
||||
path-data \
|
||||
pattern-get-type \
|
||||
pixman-rotate \
|
||||
rectangle-rounding-error \
|
||||
scale-source-surface-paint \
|
||||
|
|
@ -42,6 +44,7 @@ select-font-no-show-text \
|
|||
self-copy \
|
||||
self-intersecting \
|
||||
set-source \
|
||||
show-glyphs-many \
|
||||
show-text-current-point \
|
||||
source-clip \
|
||||
source-surface-scale-paint \
|
||||
|
|
@ -299,6 +302,7 @@ dash_offset_negative_LDADD = $(LDADDS)
|
|||
extend_reflect_LDADD = $(LDADDS)
|
||||
fill_and_stroke_LDADD = $(LDADDS)
|
||||
fill_rule_LDADD = $(LDADDS)
|
||||
font_face_get_type_LDADD = $(LDADDS)
|
||||
filter_nearest_offset_LDADD = $(LDADDS)
|
||||
ft_font_create_for_ft_face_LDADD = $(LDADDS)
|
||||
get_and_set_LDADD = $(LDADDS)
|
||||
|
|
@ -317,6 +321,7 @@ operator_source_LDADD = $(LDADDS)
|
|||
paint_LDADD = $(LDADDS)
|
||||
paint_with_alpha_LDADD = $(LDADDS)
|
||||
path_data_LDADD = $(LDADDS)
|
||||
pattern_get_type_LDADD = $(LDADDS)
|
||||
svg_surface_LDADD = $(LDADDS)
|
||||
svg_clip_LDADD = $(LDADDS)
|
||||
pixman_rotate_LDADD = $(LDADDS)
|
||||
|
|
@ -327,6 +332,7 @@ select_font_no_show_text_LDADD = $(LDADDS)
|
|||
self_copy_LDADD = $(LDADDS)
|
||||
self_intersecting_LDADD = $(LDADDS)
|
||||
set_source_LDADD = $(LDADDS)
|
||||
show_glyphs_many_LDADD = $(LDADDS)
|
||||
show_text_current_point_LDADD = $(LDADDS)
|
||||
source_clip_LDADD = $(LDADDS)
|
||||
source_surface_scale_paint_LDADD = $(LDADDS)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,21 @@
|
|||
#include "write-png.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* This is copied from cairoint.h. That makes it painful to keep in
|
||||
* sync, but the slim stuff makes cairoint.h "hard" to include when
|
||||
* not actually building the cairo library itself. Fortunately, since
|
||||
* we're checking all these values, we do have a safeguard for keeping
|
||||
* them in sync.
|
||||
*/
|
||||
typedef enum cairo_internal_surface_type {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
|
||||
} cairo_internal_surface_type_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define vsnprintf _vsnprintf
|
||||
#define access _access
|
||||
|
|
@ -163,6 +178,7 @@ typedef void
|
|||
typedef struct _cairo_test_target
|
||||
{
|
||||
const char *name;
|
||||
cairo_surface_type_t expected_type;
|
||||
cairo_content_t content;
|
||||
cairo_test_create_target_surface_t create_target_surface;
|
||||
cairo_test_write_to_png_t write_to_png;
|
||||
|
|
@ -1387,6 +1403,13 @@ cairo_test_for_target (cairo_test_t *test,
|
|||
goto UNWIND_STRINGS;
|
||||
}
|
||||
|
||||
if (cairo_surface_get_type (surface) != target->expected_type) {
|
||||
cairo_test_log ("Error: Created surface is of type %d (expected %d)\n",
|
||||
cairo_surface_get_type (surface), target->expected_type);
|
||||
ret = CAIRO_TEST_FAILURE;
|
||||
goto UNWIND_SURFACE;
|
||||
}
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
/* Clear to transparent (or black) depending on whether the target
|
||||
|
|
@ -1418,6 +1441,7 @@ cairo_test_for_target (cairo_test_t *test,
|
|||
/* Skip image check for tests with no image (width,height == 0,0) */
|
||||
if (test->width != 0 && test->height != 0) {
|
||||
int pixels_changed;
|
||||
xunlink (png_name);
|
||||
(target->write_to_png) (surface, png_name);
|
||||
if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
|
||||
pixels_changed = image_diff_flattened (png_name, ref_name, diff_name);
|
||||
|
|
@ -1436,6 +1460,7 @@ cairo_test_for_target (cairo_test_t *test,
|
|||
|
||||
UNWIND_CAIRO:
|
||||
cairo_destroy (cr);
|
||||
UNWIND_SURFACE:
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_debug_reset_static_data ();
|
||||
|
|
@ -1461,102 +1486,128 @@ cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw,
|
|||
cairo_test_target_t **targets_to_test;
|
||||
cairo_test_target_t targets[] =
|
||||
{
|
||||
{ "image", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_image_surface, cairo_surface_write_to_png, NULL},
|
||||
{ "image", CAIRO_CONTENT_COLOR,
|
||||
{ "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
|
||||
create_image_surface, cairo_surface_write_to_png, NULL},
|
||||
#ifdef CAIRO_HAS_TEST_SURFACES
|
||||
{ "test-fallback", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_test_fallback_surface, cairo_surface_write_to_png, NULL },
|
||||
{ "test-fallback", CAIRO_CONTENT_COLOR,
|
||||
{ "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
create_test_fallback_surface, cairo_surface_write_to_png, NULL },
|
||||
{ "test-meta", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_test_meta_surface, cairo_surface_write_to_png, NULL },
|
||||
{ "test-meta", CAIRO_CONTENT_COLOR,
|
||||
{ "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
create_test_meta_surface, cairo_surface_write_to_png, NULL },
|
||||
{ "test-paginated", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "test-paginated", CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_test_paginated_surface,
|
||||
test_paginated_write_to_png,
|
||||
cleanup_test_paginated },
|
||||
{ "test-paginated", CAIRO_CONTENT_COLOR,
|
||||
{ "test-paginated", CAIRO_SURFACE_TYPE_IMAGE,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
create_test_paginated_surface,
|
||||
test_paginated_write_to_png,
|
||||
cleanup_test_paginated },
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_GLITZ_SURFACE
|
||||
#if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
|
||||
{ "glitz-glx", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_cairo_glitz_glx_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_glx },
|
||||
{ "glitz-glx", CAIRO_CONTENT_COLOR,
|
||||
{ "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
|
||||
create_cairo_glitz_glx_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_glx },
|
||||
#endif
|
||||
#if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
|
||||
{ "glitz-agl", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_cairo_glitz_agl_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_agl },
|
||||
{ "glitz-agl", CAIRO_CONTENT_COLOR,
|
||||
{ "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
|
||||
create_cairo_glitz_agl_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_agl },
|
||||
#endif
|
||||
#if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
|
||||
{ "glitz-wgl", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_cairo_glitz_wgl_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_wgl },
|
||||
{ "glitz-wgl", CAIRO_CONTENT_COLOR,
|
||||
{ "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR,
|
||||
create_cairo_glitz_wgl_surface, cairo_surface_write_to_png,
|
||||
cleanup_cairo_glitz_wgl },
|
||||
#endif
|
||||
#endif /* CAIRO_HAS_GLITZ_SURFACE */
|
||||
#if 0 && CAIRO_HAS_QUARTZ_SURFACE
|
||||
{ "quartz", CAIRO_CONTENT_COLOR,
|
||||
{ "quartz", CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR,
|
||||
create_quartz_surface, cairo_surface_write_to_png,
|
||||
cleanup_quartz },
|
||||
#endif
|
||||
#if CAIRO_HAS_WIN32_SURFACE
|
||||
{ "win32", CAIRO_CONTENT_COLOR,
|
||||
{ "win32", CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR,
|
||||
create_win32_surface, cairo_surface_write_to_png, cleanup_win32 },
|
||||
#endif
|
||||
#if CAIRO_HAS_XCB_SURFACE
|
||||
{ "xcb", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_xcb_surface, cairo_surface_write_to_png, cleanup_xcb},
|
||||
#endif
|
||||
#if CAIRO_HAS_XLIB_SURFACE
|
||||
{ "xlib", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
|
||||
{ "xlib", CAIRO_CONTENT_COLOR,
|
||||
{ "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR,
|
||||
create_xlib_surface, cairo_surface_write_to_png, cleanup_xlib},
|
||||
#endif
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
{ "ps", CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
|
||||
{ "ps", CAIRO_SURFACE_TYPE_PS,
|
||||
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
|
||||
create_ps_surface, ps_surface_write_to_png, cleanup_ps },
|
||||
{ "ps", CAIRO_CONTENT_COLOR,
|
||||
|
||||
/* XXX: We expect type image here only due to a limitation in
|
||||
* the current PS/meta-surface code. A PS surface is
|
||||
* "naturally" COLOR_ALPHA, so the COLOR-only variant goes
|
||||
* through create_similar in create_ps_surface which results
|
||||
* in the similar surface being used as a source. We do not yet
|
||||
* have source support for PS/meta-surfaces, so the
|
||||
* create_similar path for all paginated surfaces currently
|
||||
* returns an image surface.*/
|
||||
{ "ps", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
|
||||
create_ps_surface, ps_surface_write_to_png, cleanup_ps },
|
||||
#endif
|
||||
#if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE
|
||||
{ "pdf", CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
|
||||
{ "pdf", CAIRO_SURFACE_TYPE_PDF,
|
||||
CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED,
|
||||
create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
|
||||
{ "pdf", CAIRO_CONTENT_COLOR,
|
||||
|
||||
/* XXX: We expect type image here only due to a limitation in
|
||||
* the current PDF/meta-surface code. A PDF surface is
|
||||
* "naturally" COLOR_ALPHA, so the COLOR-only variant goes
|
||||
* through create_similar in create_pdf_surface which results
|
||||
* in the similar surface being used as a source. We do not yet
|
||||
* have source support for PDF/meta-surfaces, so the
|
||||
* create_similar path for all paginated surfaces currently
|
||||
* returns an image surface.*/
|
||||
{ "pdf", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR,
|
||||
create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
|
||||
#endif
|
||||
#if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
|
||||
{ "svg", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_svg_surface, svg_surface_write_to_png, cleanup_svg },
|
||||
#endif
|
||||
#if CAIRO_HAS_BEOS_SURFACE
|
||||
{ "beos", CAIRO_CONTENT_COLOR,
|
||||
{ "beos", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR,
|
||||
create_beos_surface, cairo_surface_write_to_png, cleanup_beos},
|
||||
{ "beos_bitmap", CAIRO_CONTENT_COLOR,
|
||||
{ "beos_bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR,
|
||||
create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
|
||||
{ "beos_bitmap", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "beos_bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
|
||||
#endif
|
||||
|
||||
#if CAIRO_HAS_DIRECTFB_SURFACE
|
||||
{ "directfb", CAIRO_CONTENT_COLOR,
|
||||
{ "directfb", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR,
|
||||
create_directfb_surface, cairo_surface_write_to_png, cleanup_directfb},
|
||||
{ "directfb_bitmap", CAIRO_CONTENT_COLOR_ALPHA,
|
||||
{ "directfb_bitmap", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
create_directfb_bitmap_surface, cairo_surface_write_to_png,cleanup_directfb},
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
64
test/font-face-get-type.c
Normal file
64
test/font-face-get-type.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
cairo_font_face_t *font_face;
|
||||
|
||||
cairo_test_init ("font-face-get-type");
|
||||
|
||||
cairo_test_log ("Creating cairo context and obtaining a font face\n");
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_select_font_face (cr, "Bitstream Vera Sans",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
|
||||
font_face = cairo_get_font_face (cr);
|
||||
|
||||
cairo_test_log ("Testing return value of cairo_font_face_get_type\n");
|
||||
|
||||
if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_TOY) {
|
||||
cairo_test_log ("Unexpected value %d from cairo_font_face_get_type (expected %d)\n",
|
||||
cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_TOY);
|
||||
return CAIRO_TEST_FAILURE;
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return CAIRO_TEST_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -64,6 +64,13 @@ draw (cairo_t *cr, int width, int height)
|
|||
|
||||
font_face = cairo_ft_font_face_create_for_pattern (resolved);
|
||||
|
||||
if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
|
||||
cairo_test_log ("Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
|
||||
cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
|
||||
cairo_font_face_destroy (font_face);
|
||||
return CAIRO_TEST_FAILURE;
|
||||
}
|
||||
|
||||
cairo_matrix_init_identity (&font_matrix);
|
||||
|
||||
cairo_get_matrix (cr, &ctm);
|
||||
|
|
@ -82,6 +89,13 @@ draw (cairo_t *cr, int width, int height)
|
|||
FcPatternDestroy (pattern);
|
||||
FcPatternDestroy (resolved);
|
||||
|
||||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) {
|
||||
cairo_test_log ("Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n",
|
||||
cairo_scaled_font_get_type (scaled_font), CAIRO_FONT_TYPE_FT);
|
||||
cairo_scaled_font_destroy (scaled_font);
|
||||
return CAIRO_TEST_FAILURE;
|
||||
}
|
||||
|
||||
if (!ft_face) {
|
||||
cairo_test_log ("Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n");
|
||||
cairo_scaled_font_destroy (scaled_font);
|
||||
|
|
|
|||
74
test/pattern-get-type.c
Normal file
74
test/pattern-get-type.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *solid_rgb, *solid_rgba, *surface_pattern, *linear, *radial;
|
||||
|
||||
cairo_test_init ("pattern-get-type");
|
||||
|
||||
cairo_test_log ("Creating patterns of all types\n");
|
||||
|
||||
solid_rgb = cairo_pattern_create_rgb (0.0, 0.1, 0.2);
|
||||
solid_rgba = cairo_pattern_create_rgba (0.3, 0.4, 0.5, 0.6);
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
1, 1);
|
||||
surface_pattern = cairo_pattern_create_for_surface (surface);
|
||||
linear = cairo_pattern_create_linear (0.0, 0.0, 10.0, 10.0);
|
||||
radial = cairo_pattern_create_radial (10.0, 10.0, 0.1,
|
||||
10.0, 10.0, 1.0);
|
||||
|
||||
cairo_test_log ("Verifying return values of cairo_pattern_get_type\n");
|
||||
|
||||
if (cairo_pattern_get_type (solid_rgb) != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
||||
if (cairo_pattern_get_type (solid_rgba) != CAIRO_PATTERN_TYPE_SOLID)
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
||||
if (cairo_pattern_get_type (surface_pattern) != CAIRO_PATTERN_TYPE_SURFACE)
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
||||
if (cairo_pattern_get_type (linear) != CAIRO_PATTERN_TYPE_LINEAR)
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
||||
if (cairo_pattern_get_type (radial) != CAIRO_PATTERN_TYPE_RADIAL)
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
||||
cairo_test_log ("Cleaning up\n");
|
||||
|
||||
cairo_pattern_destroy (solid_rgb);
|
||||
cairo_pattern_destroy (solid_rgba);
|
||||
cairo_pattern_destroy (surface_pattern);
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_pattern_destroy (linear);
|
||||
cairo_pattern_destroy (radial);
|
||||
|
||||
return CAIRO_TEST_SUCCESS;
|
||||
}
|
||||
BIN
test/show-glyphs-many-ref.png
Normal file
BIN
test/show-glyphs-many-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 118 B |
BIN
test/show-glyphs-many-rgb24-ref.png
Normal file
BIN
test/show-glyphs-many-rgb24-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 115 B |
127
test/show-glyphs-many.c
Normal file
127
test/show-glyphs-many.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Bug history
|
||||
*
|
||||
* 2006-01-07 Jon Hellan <hellan@acm.org>
|
||||
*
|
||||
* Jon opened the following bug report:
|
||||
*
|
||||
* _XError from XRenderCompositeText8
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=5528
|
||||
*
|
||||
* 2006-03-02 Carl Worth <cworth@cworth.org>
|
||||
*
|
||||
* I wrote this test case to demonstrate the bug.
|
||||
*
|
||||
* Approach:
|
||||
*
|
||||
* Draw 65535 glyphs white-on-white all on top of each other.
|
||||
*
|
||||
* Rationale:
|
||||
*
|
||||
* The number 65535 comes from the original bug report.
|
||||
*
|
||||
* I would use cairo_show_text with a long string of 'x's say,
|
||||
* but then the surface would need to be enormous to contain
|
||||
* them. A smaller surface could be used, but I fear that at some
|
||||
* point the off-surface glyph drawing would be optimized away
|
||||
* and not exercise the bug.
|
||||
*
|
||||
* So, to keep the surface size under control, I use
|
||||
* cairo_show_glyphs which allows me to place the glyphs all on
|
||||
* top of each other. But, since cairo doesn't provide any
|
||||
* character-to-glyphs mapping, I can't get a reliable glyph
|
||||
* index (for character 'x' for example). So I just "guess" a
|
||||
* glyph index and use white-on-white drawing to ignore the
|
||||
* result. (I don't care what's drawn---I just want to ensure
|
||||
* that things don't crash.)
|
||||
*
|
||||
* Status: I replicated bug. The largest value of NUM_GLYPHS for
|
||||
* which I saw success is 21842.
|
||||
*/
|
||||
|
||||
#define TEXT_SIZE 12
|
||||
#define NUM_GLYPHS 65535
|
||||
|
||||
/* This is the index into the font for what glyph we'll draw. Since we
|
||||
* don't guarantee we'll get any particular font, we can't relibably
|
||||
* get any particular glyph. But we don't care what we draw anyway,
|
||||
* (see discussion of white-on-white drawing above). For what it's
|
||||
* worth, this appears to be giving me 'M' with Bitstream Vera
|
||||
* Sans Mono. */
|
||||
#define GLYPH_INDEX 48
|
||||
|
||||
cairo_test_t test = {
|
||||
"show-glyphs-many",
|
||||
"Test that cairo_show_glyps works when handed 'many' glyphs",
|
||||
9, 11
|
||||
};
|
||||
|
||||
static cairo_test_status_t
|
||||
draw (cairo_t *cr, int width, int height)
|
||||
{
|
||||
cairo_glyph_t glyphs[NUM_GLYPHS];
|
||||
cairo_font_options_t *font_options;
|
||||
int i;
|
||||
|
||||
/* Initialize our giant array of glyphs. */
|
||||
for (i=0; i < NUM_GLYPHS; i++) {
|
||||
glyphs[i].index = GLYPH_INDEX;
|
||||
glyphs[i].x = 1.0;
|
||||
glyphs[i].y = height - 1;
|
||||
}
|
||||
|
||||
/* Paint white background. */
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_select_font_face (cr, "Bitstream Vera Sans Mono",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_set_font_size (cr, TEXT_SIZE);
|
||||
|
||||
font_options = cairo_font_options_create ();
|
||||
|
||||
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
|
||||
|
||||
cairo_set_font_options (cr, font_options);
|
||||
cairo_font_options_destroy (font_options);
|
||||
|
||||
cairo_show_glyphs (cr, glyphs, NUM_GLYPHS);
|
||||
|
||||
return CAIRO_TEST_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return cairo_test (&test, draw);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue